Skip to contentSkip to conversation

net: convert altera_tse to driver model and phylib

PATCH Superseded Thomas Chou 3 participants 10 messages Oct 19, 2015 – Oct 23, 2015 Network drivers

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 net: convert altera_tse to driver model and phylib

Convert altera_tse to driver model and phylib.

---
 configs/nios2-generic_defconfig             |   2 +
 doc/device-tree-bindings/net/altera_tse.txt | 112 ++++
 drivers/net/Kconfig                         |   9 +
 drivers/net/altera_tse.c                    | 938 ++++++++++------------------
 drivers/net/altera_tse.h                    | 283 +++------
 include/configs/nios2-generic.h             |   8 +
 6 files changed, 536 insertions(+), 816 deletions(-)
 create mode 100644 doc/device-tree-bindings/net/altera_tse.txt
configs/nios2-generic_defconfig +2 -0
index ea07b56..fbc27ea 100644
@@ -18,6 +18,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_ALTERA_PIO=y
 CONFIG_MISC=y
 CONFIG_ALTERA_SYSID=y
+CONFIG_DM_ETH=y
+CONFIG_ALTERA_TSE=y
 CONFIG_ALTERA_JTAG_UART=y
 CONFIG_ALTERA_JTAG_UART_BYPASS=y
 CONFIG_TIMER=y
doc/device-tree-bindings/net/altera_tse.txt new file +112 -0

112 lines not on this page · raw message

drivers/net/Kconfig +9 -0
index bbec6a6..2e472b4 100644
@@ -25,6 +25,15 @@ menuconfig NETDEVICES
 
 if NETDEVICES
 
+config ALTERA_TSE
+	bool "Altera Triple-Speed Ethernet MAC support"
+	depends on DM_ETH
+	select PHYLIB
+	help
+	  This driver supports the Altera Triple-Speed (TSE) Ethernet MAC.
+	  Please find details on the "Embedded Peripherals IP User Guide"
+	  of Altera.
+
 config E1000
 	bool "Intel PRO/1000 Gigabit Ethernet support"
 	help
drivers/net/altera_tse.c +333 -605

1,139 lines not on this page · raw message

drivers/net/altera_tse.h +72 -211

377 lines not on this page · raw message

include/configs/nios2-generic.h +8 -0
index 11be6e1..76c5244 100644
@@ -33,6 +33,14 @@
 #define CONFIG_SYS_MAX_FLASH_SECT	512
 
 /*
+ * MII/PHY
+ */
+#define CONFIG_CMD_MII			1
+#define CONFIG_PHY_GIGE			1
+#define CONFIG_SYS_FAULT_ECHO_LINK_DOWN	1
+#define CONFIG_PHY_MARVELL		1
+
+/*
  * BOOTP options
  */
 #define CONFIG_BOOTP_BOOTFILESIZE
Signature · 1 line
2.1.4
#1 lore raw

PATCH 1/1 net: convert altera_tse to driver model and phylib

On Monday, October 19, 2015 at 04:36:21 AM, Thomas Chou wrote:

Hi!

Quoted 15 lines

Convert altera_tse to driver model and phylib.

---
 configs/nios2-generic_defconfig             |   2 +
 doc/device-tree-bindings/net/altera_tse.txt | 112 ++++
 drivers/net/Kconfig                         |   9 +
 drivers/net/altera_tse.c                    | 938
++++++++++------------------ drivers/net/altera_tse.h                    |
283 +++------
 include/configs/nios2-generic.h             |   8 +
 6 files changed, 536 insertions(+), 816 deletions(-)
 create mode 100644 doc/device-tree-bindings/net/altera_tse.txt
(quoted diff) +0 -0

[...]

Quoted 21 lines

/* sgdma debug - print descriptor */
static void alt_sgdma_print_desc(volatile struct alt_sgdma_descriptor
*desc) {

drivers/net/altera_tse.c +2 -15
 	debug("SGDMA DEBUG :\n");
-	debug("desc->source : 0x%x \n", (unsigned int)desc->source);
-	debug("desc->destination : 0x%x \n", (unsigned int)desc->destination);
-	debug("desc->next : 0x%x \n", (unsigned int)desc->next);
-	debug("desc->source_pad : 0x%x \n", (unsigned int)desc->source_pad);
-	debug("desc->destination_pad : 0x%x \n",
-	      (unsigned int)desc->destination_pad);
-	debug("desc->next_pad : 0x%x \n", (unsigned int)desc->next_pad);
-	debug("desc->bytes_to_transfer : 0x%x \n",
-	      (unsigned int)desc->bytes_to_transfer);
-	debug("desc->actual_bytes_transferred : 0x%x \n",
-	      (unsigned int)desc->actual_bytes_transferred);
-	debug("desc->descriptor_status : 0x%x \n",
-	      (unsigned int)desc->descriptor_status);
-	debug("desc->descriptor_control : 0x%x \n",
-	      (unsigned int)desc->descriptor_control);
+	debug("desc->source : 0x%x\n", (unsigned int)desc->source);
+	debug("desc->destination : 0x%x\n", (unsigned int)desc->destination);

drivers/net/altera_tse.c line 38

Quoted 10 lines
drivers/net/altera_tse.c +9 -0
+	debug("desc->next : 0x%x\n", (unsigned int)desc->next);
+	debug("desc->source_pad : 0x%x\n", desc->source_pad);
+	debug("desc->destination_pad : 0x%x\n", desc->destination_pad);
+	debug("desc->next_pad : 0x%x\n", desc->next_pad);
+	debug("desc->bytes_to_transfer : 0x%x\n", desc->bytes_to_transfer);
+	debug("desc->actual_bytes_transferred : 0x%x\n",
+	      desc->actual_bytes_transferred);
+	debug("desc->descriptor_status : 0x%x\n", desc->descriptor_status);
+	debug("desc->descriptor_control : 0x%x\n", desc->descriptor_control);
 }

Looks like a cleanup part of the patch, not a conversion, so you might want to split this out. Btw. while at it, please drop those (unsigned int) casts.

Quoted 15 lines
drivers/net/altera_tse.c +2 -2
-/* This is a generic routine that the SGDMA mode-specific routines
+/*
+ * This is a generic routine that the SGDMA mode-specific routines
  * call to populate a descriptor.
  * arg1	    :pointer to first SGDMA descriptor.
  * arg2	    :pointer to next  SGDMA descriptor.
@@ -108,7 +107,6 @@ static void alt_sgdma_construct_descriptor_burst(
 	 * pointing at this descriptor, it will not run (via the "owned by
 	 * hardware" bit) until all other descriptor has been set up.
 	 */
-
 	desc->descriptor_control =
 	    ((ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK) |
 	     (generate_eop ?

drivers/net/altera_tse.c static void alt_sgdma_construct_descriptor_burst( · line 122

Quoted 5 lines
drivers/net/altera_tse.c +0 -1
@@ -121,18 +119,19 @@ static void alt_sgdma_construct_descriptor_burst(
 		    );
 }
 
-static int alt_sgdma_do_sync_transfer(volatile struct alt_sgdma_registers
 *dev, -			       volatile struct alt_sgdma_descriptor 

*desc)

drivers/net/altera_tse.c static void alt_sgdma_construct_descriptor_burst( · line 124

Quoted 3 lines
drivers/net/altera_tse.c +3 -0
+static int alt_sgdma_do_sync_transfer(
+	volatile struct alt_sgdma_registers *regs,
+	volatile struct alt_sgdma_descriptor *desc)

The volatiles are almost certainly wrong, so they should go.

Oh wait, is this driver NOT using any I/O accessors ? :-O

Quoted 18 lines
drivers/net/altera_tse.c +2 -2
 {
 	unsigned int status;
 	int counter = 0;
 
 	/* Wait for any pending transfers to complete */
 	alt_sgdma_print_desc(desc);
-	status = dev->status;
+	status = regs->status;
 
 	counter = 0;
-	while (dev->status & ALT_SGDMA_STATUS_BUSY_MSK) {
+	while (regs->status & ALT_SGDMA_STATUS_BUSY_MSK) {
 		if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR)
 			break;
 	}
@@ -144,12 +143,12 @@ static int alt_sgdma_do_sync_transfer(volatile struct

alt_sgdma_registers *dev, * Clear any (previous) status register information

drivers/net/altera_tse.c static int alt_sgdma_do_sync_transfer(volatile struct alt_sgdma_registers *dev, · line 149

Quoted 8 lines
drivers/net/altera_tse.c +2 -2
 	 * that might occlude our error checking later.
 	 */
-	dev->status = 0xFF;
+	regs->status = 0xFF;
 
 	/* Point the controller at the descriptor */
-	dev->next_descriptor_pointer = (unsigned int)desc & 0x1FFFFFFF;
+	regs->next_descriptor_pointer = (unsigned int)desc & 0x1FFFFFFF;

This looks pretty wrong, with the cast and all.

Quoted 12 lines
drivers/net/altera_tse.c +1 -1
 	debug("next desc in sgdma 0x%x\n",
-	      (unsigned int)dev->next_descriptor_pointer);
+	      (unsigned int)regs->next_descriptor_pointer);
 
 	/*
 	 * Set up SGDMA controller to:
@@ -157,30 +156,31 @@ static int alt_sgdma_do_sync_transfer(volatile struct

alt_sgdma_registers *dev, * - Run once a valid descriptor is written to controller

drivers/net/altera_tse.c +0 -1
 	 * - Stop on an error with any particular descriptor
 	 */
-	dev->control = (ALT_SGDMA_CONTROL_RUN_MSK |

drivers/net/altera_tse.c static int alt_sgdma_do_sync_transfer(volatile struct alt_sgdma_registers *dev, · line 166

Quoted 10 lines
drivers/net/altera_tse.c +3 -2
+	regs->control = (ALT_SGDMA_CONTROL_RUN_MSK |
 			ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK);
 
 	/* Wait for the descriptor (chain) to complete */
-	status = dev->status;
+	status = regs->status;
 	debug("wait for sgdma....");
-	while (dev->status & ALT_SGDMA_STATUS_BUSY_MSK)
+	while (regs->status & ALT_SGDMA_STATUS_BUSY_MSK)
 		;

Eventually, this unbounded wait should be nuked and replaced with a proper wait with timeout. In case you're up to it, that'd be real nice.

Quoted 16 lines
drivers/net/altera_tse.c +3 -3
 	debug("done\n");
 
 	/* Clear Run */
-	dev->control = (dev->control & (~ALT_SGDMA_CONTROL_RUN_MSK));
+	regs->control = (regs->control & (~ALT_SGDMA_CONTROL_RUN_MSK));
 
 	/* Get & clear status register contents */
-	status = dev->status;
-	dev->status = 0xFF;
+	status = regs->status;
+	regs->status = 0xFF;
 
 	/* we really should check if the transfer completes properly */
 	debug("tx sgdma status = 0x%x", status);
 	return 0;
 }

[...]

Quoted 10 lines
drivers/net/altera_tse.c +9 -1
-static int tse_eth_rx(struct eth_device *dev)
+static void tse_eth_rx_setup(struct altera_tse_priv *priv)
+{
+	uchar *rx_buf = net_rx_packets[priv->rx_cur & 1];
+	volatile struct alt_sgdma_descriptor *rx_desc = priv->rx_desc;
+
+	invalidate_dcache_range((unsigned long)rx_buf,
+				(unsigned long)rx_buf + PKTSIZE_ALIGN);
+	alt_sgdma_construct_descriptor_burst(
+		&rx_desc[0],

drivers/net/altera_tse.c static int tse_eth_send(struct eth_device *dev, void *packet, int length) · line 381

Quoted 10 lines
drivers/net/altera_tse.c +10 -0
+		&rx_desc[1],
+		(unsigned int)0x0,	/* read addr */
+		(unsigned int *)rx_buf,
+		0x0,	/* length or EOP */
+		0x0,	/* gen eop */
+		0x0,	/* read fixed */
+		0x0,	/* write fixed or sop */
+		0x0,	/* read burst */
+		0x0,	/* write burst */
+		0x0	/* channel */

You might want to pass the args as a structure instead of having a function with billion arguments. But that's just a suggestion for improvement.

Quoted 5 lines
drivers/net/altera_tse.c +5 -0
+		);
+
+	/* setup the sgdma */
+	alt_sgdma_do_async_transfer(priv->sgdma_rx, &rx_desc[0]);
+}

[...]

Quoted 20 lines
drivers/net/altera_tse.c +20 -0
+static int altera_tse_probe(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_platdata(dev);
+	struct altera_tse_priv *priv = dev_get_priv(dev);
+	const void *blob = gd->fdt_blob;
+	int node = dev->of_offset;
+	const char *list, *end;
+	const fdt32_t *cell;
+	void *base, *desc_mem = NULL;
+	unsigned long addr, size;
+	int len, idx;
+	int ret;
+
+	/* decode regs, assume address-cells and size-cells are both one */
+	list = fdt_getprop(blob, node, "reg-names", &len);
+	if (!list)
+		return -ENOENT;
+	end = list + len;
+	cell = fdt_getprop(blob, node, "reg", &len);
+	if (!cell)

drivers/net/altera_tse.c static int tse_eth_init(struct eth_device *dev, bd_t * bd) · line 614

Quoted 10 lines
drivers/net/altera_tse.c +10 -0
+		return -ENOENT;
+	idx = 0;
+	while (list < end) {
+		addr = fdt_translate_address((void *)blob,
+					     node, cell + idx);
+		size = fdt_addr_to_cpu(cell[idx + 1]);
+		base = ioremap(addr, size);
+		len = strlen(list);
+		if (strcmp(list, "control_port") == 0)
+			priv->mac_dev = base;

fdtdec_get_addr() won't do here?

Quoted 9 lines
drivers/net/altera_tse.c +8 -0
+		else if (strcmp(list, "rx_csr") == 0)
+			priv->sgdma_rx = base;
+		else if (strcmp(list, "tx_csr") == 0)
+			priv->sgdma_tx = base;
+		else if (strcmp(list, "s1") == 0)
+			desc_mem = base;
+		idx += 2;
+		list += (len + 1);
 	}

[...]

#2 lore raw

PATCH 1/1 net: convert altera_tse to driver model and phylib

Hi Marek,

Quoted 11 lines · Marek Vasut
Quoted 11 lines
drivers/net/altera_tse.c +11 -0
+	/* decode regs, assume address-cells and size-cells are both one */
+	list = fdt_getprop(blob, node, "reg-names", &len);
+	if (!list)
+		return -ENOENT;
+	end = list + len;
+	cell = fdt_getprop(blob, node, "reg", &len);
+	if (!cell)
+		return -ENOENT;
+	idx = 0;
+	while (list < end) {
+		addr = fdt_translate_address((void *)blob,
Quoted 8 lines

drivers/net/altera_tse.c static int tse_eth_init(struct eth_device *dev, bd_t * bd) · line 614

Quoted 6 lines
drivers/net/altera_tse.c +6 -0
+					     node, cell + idx);
+		size = fdt_addr_to_cpu(cell[idx + 1]);
+		base = ioremap(addr, size);
+		len = strlen(list);
+		if (strcmp(list, "control_port") == 0)
+			priv->mac_dev = base;

fdtdec_get_addr() won't do here?

There are multiple "reg" tuples, and need to match "reg-names". That's beyond fdtdec_get_addr().

	tse_mac: ethernet at 0x4000 {
		compatible = "altr,tse-1.0";
		reg = <0x00004000 0x00000400>,
			<0x00004400 0x00000040>,
			<0x00004800 0x00000040>,
			<0x00002000 0x00002000>;
		reg-names = "control_port", "rx_csr", "tx_csr", "s1";

Thanks a lot for your reviews.

Best regards,
Thomas

#3 lore raw

PATCH 1/1 net: convert altera_tse to driver model and phylib

Quoted 1 line · Thomas Chou

Hi Marek,

Hi!

Quoted 32 lines · Marek Vasut
Quoted 11 lines
Quoted 11 lines
drivers/net/altera_tse.c +11 -0
+	/* decode regs, assume address-cells and size-cells are both one */
+	list = fdt_getprop(blob, node, "reg-names", &len);
+	if (!list)
+		return -ENOENT;
+	end = list + len;
+	cell = fdt_getprop(blob, node, "reg", &len);
+	if (!cell)
+		return -ENOENT;
+	idx = 0;
+	while (list < end) {
+		addr = fdt_translate_address((void *)blob,
Quoted 8 lines

drivers/net/altera_tse.c static int tse_eth_init(struct eth_device *dev, bd_t * bd) · line 614

Quoted 6 lines
drivers/net/altera_tse.c +6 -0
+					     node, cell + idx);
+		size = fdt_addr_to_cpu(cell[idx + 1]);
+		base = ioremap(addr, size);
+		len = strlen(list);
+		if (strcmp(list, "control_port") == 0)
+			priv->mac_dev = base;

fdtdec_get_addr() won't do here?

There are multiple "reg" tuples, and need to match "reg-names". That's beyond fdtdec_get_addr().

	tse_mac: ethernet at 0x4000 {
		compatible = "altr,tse-1.0";
		reg = <0x00004000 0x00000400>,
			<0x00004400 0x00000040>,
			<0x00004800 0x00000040>,
			<0x00002000 0x00002000>;
		reg-names = "control_port", "rx_csr", "tx_csr", "s1";
Quoted 1 line

Thanks a lot for your reviews.

Gotcha, thanks!

Best regards,
Marek Vasut

#4 lore raw

PATCH v2 1/1 net: convert altera_tse to driver model and phylib

In reply to Thomas Chou

Convert altera_tse to driver model and phylib.

---
v2
remove volatile and use I/O accessors as suggested by Marek. use virt_to_phys() to get dma address.
add free_pkt() ops.
add timeout to loop.
allocate cache aligned rx buffer.
refactor sgdma calls.

 configs/nios2-generic_defconfig             |    2 +
 doc/device-tree-bindings/net/altera_tse.txt |  112 +++
 drivers/net/Kconfig                         |    9 +
 drivers/net/altera_tse.c                    | 1150 +++++++++------------------
 drivers/net/altera_tse.h                    |  277 +------
 include/configs/nios2-generic.h             |    8 +
 6 files changed, 526 insertions(+), 1032 deletions(-)
 create mode 100644 doc/device-tree-bindings/net/altera_tse.txt
configs/nios2-generic_defconfig +2 -0
index ea07b56..fbc27ea 100644
@@ -18,6 +18,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_ALTERA_PIO=y
 CONFIG_MISC=y
 CONFIG_ALTERA_SYSID=y
+CONFIG_DM_ETH=y
+CONFIG_ALTERA_TSE=y
 CONFIG_ALTERA_JTAG_UART=y
 CONFIG_ALTERA_JTAG_UART_BYPASS=y
 CONFIG_TIMER=y
doc/device-tree-bindings/net/altera_tse.txt new file +112 -0

112 lines not on this page · raw message

drivers/net/Kconfig +9 -0
index bbec6a6..a03a95d 100644
@@ -25,6 +25,15 @@ menuconfig NETDEVICES
 
 if NETDEVICES
 
+config ALTERA_TSE
+	bool "Altera Triple-Speed Ethernet MAC support"
+	depends on DM_ETH
+	select PHYLIB
+	help
+	  This driver supports the Altera Triple-Speed (TSE) Ethernet MAC.
+	  Please find details on the "Triple-Speed Ethernet MegaCore Function
+	  Resource Center" of Altera.
+
 config E1000
 	bool "Intel PRO/1000 Gigabit Ethernet support"
 	help
drivers/net/altera_tse.c +374 -776

1,320 lines not on this page · raw message

drivers/net/altera_tse.h +21 -256

334 lines not on this page · raw message

include/configs/nios2-generic.h +8 -0
index 11be6e1..76c5244 100644
@@ -33,6 +33,14 @@
 #define CONFIG_SYS_MAX_FLASH_SECT	512
 
 /*
+ * MII/PHY
+ */
+#define CONFIG_CMD_MII			1
+#define CONFIG_PHY_GIGE			1
+#define CONFIG_SYS_FAULT_ECHO_LINK_DOWN	1
+#define CONFIG_PHY_MARVELL		1
+
+/*
  * BOOTP options
  */
 #define CONFIG_BOOTP_BOOTFILESIZE
Signature · 1 line
2.1.4
#5 lore raw

PATCH v2 1/1 net: convert altera_tse to driver model and phylib

Quoted 12 lines · Thomas Chou

Convert altera_tse to driver model and phylib.

---
v2
remove volatile and use I/O accessors as suggested by Marek. use virt_to_phys() to get dma address.
add free_pkt() ops.
add timeout to loop.
allocate cache aligned rx buffer.
refactor sgdma calls.

Quoted 9 lines
 configs/nios2-generic_defconfig             |    2 +
 doc/device-tree-bindings/net/altera_tse.txt |  112 +++
 drivers/net/Kconfig                         |    9 +
 drivers/net/altera_tse.c                    | 1150
+++++++++------------------ drivers/net/altera_tse.h                    | 
277 +------
 include/configs/nios2-generic.h             |    8 +
 6 files changed, 526 insertions(+), 1032 deletions(-)
 create mode 100644 doc/device-tree-bindings/net/altera_tse.txt

Hrm, either I didn't look properly or you did really great job fixing this patch up ;-)

Thanks!

Best regards,
Marek Vasut

#6 lore raw

PATCH v2 1/1 net: convert altera_tse to driver model and phylib

In reply to Thomas Chou

Hi Thomas,

Quoted 13 lines · Thomas Chou

Convert altera_tse to driver model and phylib.

---
v2
remove volatile and use I/O accessors as suggested by Marek. use virt_to_phys() to get dma address.
add free_pkt() ops.
add timeout to loop.
allocate cache aligned rx buffer.
refactor sgdma calls.

Quoted 9 lines
 configs/nios2-generic_defconfig             |    2 +
 doc/device-tree-bindings/net/altera_tse.txt |  112 +++
 drivers/net/Kconfig                         |    9 +
 drivers/net/altera_tse.c                    | 1150 +++++++++------------------
 drivers/net/altera_tse.h                    |  277 +------
 include/configs/nios2-generic.h             |    8 +
 6 files changed, 526 insertions(+), 1032 deletions(-)
 create mode 100644 doc/device-tree-bindings/net/altera_tse.txt

This is a very nice piece of work.

[snip]

Quoted 40 lines
drivers/net/altera_tse.c +15 -21
-static void tse_eth_reset(struct eth_device *dev)
+static void tse_eth_reset(struct altera_tse_priv *priv)
 {
-       /* stop sgdmas, disable tse receive */
-       struct altera_tse_priv *priv = dev->priv;
-       volatile struct alt_tse_mac *mac_dev = priv->mac_dev;
-       volatile struct alt_sgdma_registers *rx_sgdma = priv->sgdma_rx;
-       volatile struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx;
-       int counter;
-       volatile struct alt_sgdma_descriptor *rx_desc =
-           (volatile struct alt_sgdma_descriptor *)&priv->rx_desc[0];
+       struct alt_tse_mac *mac_dev = priv->mac_dev;
+       struct alt_sgdma_registers *rx_sgdma = priv->sgdma_rx;
+       struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx;
+       struct alt_sgdma_descriptor *rx_desc = priv->rx_desc;
+       unsigned int status;
+       int ret;
+       ulong ctime;
 
        /* clear rx desc & wait for sgdma to complete */
        rx_desc->descriptor_control = 0;
-       rx_sgdma->control = 0;
-       counter = 0;
-       while (rx_sgdma->status & ALT_SGDMA_STATUS_BUSY_MSK) {
-               if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR)
-                       break;
-       }
-
-       if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) {
-               debug("Timeout waiting for rx sgdma!\n");
-               rx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
-               rx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
-       }
+       writel(0, &rx_sgdma->control);
+       ret = alt_sgdma_wait_transfer(rx_sgdma);
+       if (ret == -ETIMEDOUT)
+               writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK,
+                      &rx_sgdma->control);
+
+       writel(0, &tx_sgdma->control);

drivers/net/altera_tse.c static int tse_adjust_link(struct altera_tse_priv *priv) · line 370

Quoted 10 lines
drivers/net/altera_tse.c +4 -5
+       ret = alt_sgdma_wait_transfer(tx_sgdma);
+       if (ret == -ETIMEDOUT)
+               writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK,
+                      &tx_sgdma->control);
 
-       counter = 0;
-       tx_sgdma->control = 0;
-       while (tx_sgdma->status & ALT_SGDMA_STATUS_BUSY_MSK) {
-               if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR)
-                       break;

It looks like this function can fail in various ways - should it not return an error?

[snip]

drivers/net/altera_tse.c static int tse_adjust_link(struct altera_tse_priv *priv) · line 420

Quoted 3 lines
drivers/net/altera_tse.c +2 -0
+static int altera_tse_free_pkt(struct udevice *dev, uchar *packet,
+                              int length)
 {

These functions seem to just call other functions. Perhaps you might consider moving the code here a follow-on patch?

Quoted 52 lines
drivers/net/altera_tse.c +43 -9
-static int tse_eth_init(struct eth_device *dev, bd_t * bd)
-{
-       int dat;
-       struct altera_tse_priv *priv = dev->priv;
-       volatile struct alt_tse_mac *mac_dev = priv->mac_dev;
-       volatile struct alt_sgdma_descriptor *tx_desc = priv->tx_desc;
-       volatile struct alt_sgdma_descriptor *rx_desc = priv->rx_desc;
-       volatile struct alt_sgdma_descriptor *rx_desc_cur =
-           (volatile struct alt_sgdma_descriptor *)&rx_desc[0];
+       /*
+        * decode regs, assume address-cells and size-cells are both one.
+        * there are multiple reg tuples, and they need to match with
+        * reg-names.
+        */
+       list = fdt_getprop(blob, node, "reg-names", &len);
+       if (!list)
+               return -ENOENT;
+       end = list + len;
+       cell = fdt_getprop(blob, node, "reg", &len);
+       if (!cell)
+               return -ENOENT;
+       idx = 0;
+       while (list < end) {
+               addr = fdt_translate_address((void *)blob,
+                                            node, cell + idx);
+               size = fdt_addr_to_cpu(cell[idx + 1]);
+               base = ioremap(addr, size);
+               len = strlen(list);
+               if (strcmp(list, "control_port") == 0)
+                       priv->mac_dev = base;
+               else if (strcmp(list, "rx_csr") == 0)
+                       priv->sgdma_rx = base;
+               else if (strcmp(list, "tx_csr") == 0)
+                       priv->sgdma_tx = base;
+               else if (strcmp(list, "s1") == 0)
+                       desc_mem = base;
+               idx += 2;
+               list += (len + 1);
+       }
+       /* decode fifo depth */
+       priv->rx_fifo_depth = fdtdec_get_int(blob, node,
+               "rx-fifo-depth", 0);
+       priv->tx_fifo_depth = fdtdec_get_int(blob, node,
+               "tx-fifo-depth", 0);
+       /* decode phy */
+       addr = fdtdec_get_int(blob, node,
+                             "phy-handle", 0);
+       addr = fdt_node_offset_by_phandle(blob, addr);
+       priv->phyaddr = fdtdec_get_int(blob, addr,
+               "reg", 0);
+       /* init desc */
+       len = sizeof(struct alt_sgdma_descriptor) * 4;

drivers/net/altera_tse.c static int tse_adjust_link(struct altera_tse_priv *priv) · line 510

Quoted 10 lines
drivers/net/altera_tse.c +10 -0
+       if (!desc_mem) {
+               desc_mem = dma_alloc_coherent(len, &addr);
+               if (!desc_mem)
+                       return -ENOMEM;
+       }
+       memset(desc_mem, 0, len);
+       priv->tx_desc = desc_mem;
+       priv->rx_desc = priv->tx_desc + 2;
+       /* allocate recv packet buffer */
+       priv->rx_buf = malloc_cache_aligned(PKTSIZE_ALIGN);

Can you just use

uint8_t rx_buf[PKTSIZE_ALIGN]

in this 'priv' structure? Why do a separate malloc()?

Regards,
Simon

#7 lore raw

PATCH v2 1/1 net: convert altera_tse to driver model and phylib

Hi Simon,

Quoted 12 lines · Simon Glass
Quoted 12 lines
drivers/net/altera_tse.c +11 -0
+       writel(0, &rx_sgdma->control);
+       ret = alt_sgdma_wait_transfer(rx_sgdma);
+       if (ret == -ETIMEDOUT)
+               writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK,
+                      &rx_sgdma->control);
+
+       writel(0, &tx_sgdma->control);
+       ret = alt_sgdma_wait_transfer(tx_sgdma);
+       if (ret == -ETIMEDOUT)
+               writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK,
+                      &tx_sgdma->control);
Quoted 8 lines

drivers/net/altera_tse.c static int tse_adjust_link(struct altera_tse_priv *priv) · line 370

Quoted 5 lines
drivers/net/altera_tse.c +0 -5
-       counter = 0;
-       tx_sgdma->control = 0;
-       while (tx_sgdma->status & ALT_SGDMA_STATUS_BUSY_MSK) {
-               if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR)
-                       break;

It looks like this function can fail in various ways - should it not return an error?

We would like to reset sgdma here. But Altera advices that software reset should be used with care to avoid bus lock up. So we wait the sgdma transfer to stop before applying a software reset.

If the sgdma stopped successfully, there is no need to do soft reset. Otherwise, we simply apply a soft reset and go on.

Quoted 9 lines

[snip]

drivers/net/altera_tse.c static int tse_adjust_link(struct altera_tse_priv *priv) · line 420

Quoted 3 lines
drivers/net/altera_tse.c +2 -0
+static int altera_tse_free_pkt(struct udevice *dev, uchar *packet,
+                              int length)
  {

These functions seem to just call other functions. Perhaps you might consider moving the code here a follow-on patch?

I will move the code into net ops for those with a single caller.

Quoted 9 lines

drivers/net/altera_tse.c static int tse_adjust_link(struct altera_tse_priv *priv) · line 510

Quoted 2 lines
drivers/net/altera_tse.c +2 -0
+       /* allocate recv packet buffer */
+       priv->rx_buf = malloc_cache_aligned(PKTSIZE_ALIGN);

Can you just use

uint8_t rx_buf[PKTSIZE_ALIGN]

in this 'priv' structure? Why do a separate malloc()?

The rx dma buffer need to be cache aligned. This is the point that Marek and I have discussed for a while. Though a __algined() modifier might work this way,

	char rx_buf[PKTSIZE_ALIGN] __aligned(ARCH_DMA_MINALIGN);

I do believe a more explicit and trusted malloc with cache aligned is better.

Thanks a lot for your review.

Best regards,
Thomas

#8 lore raw

PATCH v3 1/1 net: convert altera_tse to driver model and phylib

In reply to Thomas Chou

Convert altera_tse to driver model and phylib.

---
v2
remove volatile and use I/O accessors as suggested by Marek. use virt_to_phys() to get dma address.
add free_pkt() ops.
add timeout to loop.
allocate cache aligned rx buffer.
refactor sgdma calls.
v3
move the code into net ops for those with a single caller.

 configs/nios2-generic_defconfig             |    2 +
 doc/device-tree-bindings/net/altera_tse.txt |  112 +++
 drivers/net/Kconfig                         |    9 +
 drivers/net/altera_tse.c                    | 1143 +++++++++------------------
 drivers/net/altera_tse.h                    |  277 +------
 include/configs/nios2-generic.h             |    8 +
 6 files changed, 504 insertions(+), 1047 deletions(-)
 create mode 100644 doc/device-tree-bindings/net/altera_tse.txt
configs/nios2-generic_defconfig +2 -0
index ea07b56..fbc27ea 100644
@@ -18,6 +18,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_ALTERA_PIO=y
 CONFIG_MISC=y
 CONFIG_ALTERA_SYSID=y
+CONFIG_DM_ETH=y
+CONFIG_ALTERA_TSE=y
 CONFIG_ALTERA_JTAG_UART=y
 CONFIG_ALTERA_JTAG_UART_BYPASS=y
 CONFIG_TIMER=y
doc/device-tree-bindings/net/altera_tse.txt new file +112 -0

112 lines not on this page · raw message

drivers/net/Kconfig +9 -0
index bbec6a6..a03a95d 100644
@@ -25,6 +25,15 @@ menuconfig NETDEVICES
 
 if NETDEVICES
 
+config ALTERA_TSE
+	bool "Altera Triple-Speed Ethernet MAC support"
+	depends on DM_ETH
+	select PHYLIB
+	help
+	  This driver supports the Altera Triple-Speed (TSE) Ethernet MAC.
+	  Please find details on the "Triple-Speed Ethernet MegaCore Function
+	  Resource Center" of Altera.
+
 config E1000
 	bool "Intel PRO/1000 Gigabit Ethernet support"
 	help
drivers/net/altera_tse.c +352 -791

1,298 lines not on this page · raw message

drivers/net/altera_tse.h +21 -256

334 lines not on this page · raw message

include/configs/nios2-generic.h +8 -0
index 11be6e1..76c5244 100644
@@ -33,6 +33,14 @@
 #define CONFIG_SYS_MAX_FLASH_SECT	512
 
 /*
+ * MII/PHY
+ */
+#define CONFIG_CMD_MII			1
+#define CONFIG_PHY_GIGE			1
+#define CONFIG_SYS_FAULT_ECHO_LINK_DOWN	1
+#define CONFIG_PHY_MARVELL		1
+
+/*
  * BOOTP options
  */
 #define CONFIG_BOOTP_BOOTFILESIZE
Signature · 1 line
2.1.4
#9 lore raw

PATCH v3 1/1 net: convert altera_tse to driver model and phylib

Quoted 16 lines · Thomas Chou

Convert altera_tse to driver model and phylib.

---
v2
remove volatile and use I/O accessors as suggested by Marek. use virt_to_phys() to get dma address.
add free_pkt() ops.
add timeout to loop.
allocate cache aligned rx buffer.
refactor sgdma calls.
v3
move the code into net ops for those with a single caller.

Quoted 9 lines
  configs/nios2-generic_defconfig             |    2 +
  doc/device-tree-bindings/net/altera_tse.txt |  112 +++
  drivers/net/Kconfig                         |    9 +
  drivers/net/altera_tse.c                    | 1143 +++++++++------------------
  drivers/net/altera_tse.h                    |  277 +------
  include/configs/nios2-generic.h             |    8 +
  6 files changed, 504 insertions(+), 1047 deletions(-)

create mode 100644 doc/device-tree-bindings/net/altera_tse.txt

Applied to u-boot-nios.