# Mvneta: help with a voltage patch

**URL:** <https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226>\
**Category:** For Developers\
**Created:** [May 19, 2020, 7:27pm UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226 "2020-05-19T19:27:51Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![danitool](https://forum.openwrt.org/letter_avatar/danitool/32/5_5575768a8748004e209b776fc1b2916d.png) [@danitool](https://forum.openwrt.org/u/danitool)\
**Post date:** [May 19, 2020, 7:27pm UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/1 "2020-05-19T19:27:51Z")

</div>

Hello,  
It turns out that my [LinkStation LS421DE](https://openwrt.org/toh/buffalo/ls421de) has a bug on the ethernet port wich makes the connection to behave randomly unstable. After hours of testing I catched the problem.

It is a discrepancy between the ethernet voltage and the PHY voltage:

- The ethernet at the Marvell SoC is configured by default to operate at 3.3 volts
- The PHY only supports 1.8 volts.

The SoC can be configured to force the RGMII pins use the 1.8volts correct voltage by changing the value of a couple of bytes in the internal registers. Looks like the manufacturer wasn't aware of this, because it isn't configured by the bootloader nor the stock firmware.

In Openwrt of course the problem is still present. So I looked for a solution. There are several options to fix it:

1. **Setting the registers from userspace** : easy, it can be done with devmem, but Openwrt comes with _/dev/mem_ disabled. So it needs compiling an Openwrt image with _/dev/mem_ enabled. Not easy for all users.
2. **Patching the bootloader** : I already did it patching the stuff where the RAM is initialized, it apparently works fine. But again this is not an easy option, to flash a new bootloader which can cause a potential brick.
3. **Patching the kernel** : this seems to be the best option, it won't require user intervention once Openwrt is installed. I also made a patch, see below.

This is the mvneta driver, where I made the patch:  
[https://elixir.bootlin.com/linux/v5.4.41/source/drivers/net/ethernet/marvell/mvneta.c](https://elixir.bootlin.com/linux/v5.4.41/source/drivers/net/ethernet/marvell/mvneta.c)

I noticed this is not the only one manufacturer which doesn't set the voltage correctly. Therefore other devices may benefit the patch.

However I'm not sure if patching mvneta is the best idea for fixing this issue. From my point of view it is ok, because it unconditionally will establish the correct voltage without requiring any manual intervention, and saving headaches because the bug isn't easy to detect.

```
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -459,6 +459,8 @@
 	bool neta_armada3700;
 	u16 rx_offset_correction;
 	const struct mbus_dram_target_info *dram_target_info;
+
+	phys_addr_t regaddr;
 };
 
 /* The mvneta_tx_desc and mvneta_rx_desc structures describe the
@@ -3653,6 +3655,63 @@
 	.mac_link_up = mvneta_mac_link_up,
 };
 
+#define MARVELL_PHY_ID_88E1318S	0x01410e90
+#define MARVELL_PHY_ID_88E1518	0x01410dd1
+#define VDDO_PADS_VOLTAGE_OFFS 0x184E0
+
+/* Armada 370/XP RGMII pins voltage is 3v3 as default. It must be set
+ * to 1v8 with Marvell 88E1318S/88E1518 PHYs since they only support
+ * this voltage. The connection will be randomly unstable otherwise.
+ */
+static void mvneta_fix_voltage(struct mvneta_port *pp)
+{
+	void __iomem *vddo_addr;
+	bool is_port0;
+	u32 reg, phyid;
+
+	/* 0x70000 is the port0, 0x74000 is the port1 */
+	is_port0 = !(pp->regaddr & GENMASK(14, 12));
+
+	/* Get the PHY ID */
+	phyid = pp->dev->phydev->phy_id;
+
+	/* base address: 0xf1000000 or 0xd0000000 */
+	vddo_addr = ioremap((pp->regaddr & GENMASK(31,24)) +
+ VDDO_PADS_VOLTAGE_OFFS, 4);
+
+ /* Set the RGMII pins voltage at the SoC to 1v8 */
+	if (phyid == MARVELL_PHY_ID_88E1318S ||
+ phyid == MARVELL_PHY_ID_88E1518) {
+ if (of_machine_is_compatible("marvell,armada370")){
+ if (is_port0) {
+ reg = readl(vddo_addr);
+ /* MPP pins 5 to 16 */
+ reg &= ~GENMASK(3,2);
+ } else {
+ reg = readl(vddo_addr);
+ /* MPP pins 17 to 31 */
+ reg &= ~GENMASK(5,4);
+ }
+ }
+ else if (of_machine_is_compatible("marvell,armadaxp")) {
+ if (is_port0) {
+ reg = readl(vddo_addr);
+ /* MPP pins 0 to 11 */
+ reg &= ~GENMASK(1,0);
+ } else {
+ reg = readl(vddo_addr);
+ /* MPP pins 12 to 23 */
+ reg &= ~GENMASK(3,2);
+ }
+ }
+ else
+ return;
+
+ writel(reg, vddo_addr);
+ netdev_info(pp->dev, "VDDO voltage asserted: 1v8\n");
+	}
+}
+
 static int mvneta_mdio_probe(struct mvneta_port *pp)
 {
 	struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
@@ -3661,6 +3720,9 @@
 	if (err)
 		netdev_err(pp->dev, "could not attach PHY: %d\n", err);
 
+	if (of_machine_is_compatible("marvell,armada-370-xp"))
+ mvneta_fix_voltage(pp);
+
 	phylink_ethtool_get_wol(pp->phylink, &wol);
 	device_set_wakeup_capable(&pp->dev->dev, !!wol.supported);
 
@@ -4553,6 +4615,7 @@
 	pp->comphy = comphy;
 	pp->phy_interface = phy_mode;
 	pp->dn = dn;
+	pp->regaddr = pdev->resource->start;
 
 	pp->rxq_def = rxq_def;
 	pp->indir[0] = rxq_def;

```

Another option could be to use device tree adding a property to the mvneta driver. But again I'm touching this driver. Or maybe the MVEBU pinctrl driver... I don't see how to articulate both drivers with the device tree to achieve the target.

Is it good this patch?, would be accepted by Openwrt or upstream?

Regards  
Daniel

---

<div class="post-metadata">

**Author:** ![robimarko](https://forum.openwrt.org/user_avatar/forum.openwrt.org/robimarko/32/617_2.png) [@robimarko](https://forum.openwrt.org/u/robimarko)\
**Post date:** [May 19, 2020, 8:57pm UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/2 "2020-05-19T20:57:20Z")

</div>

The best way to approach this would be to add a device tree binding for this case that would set the correct voltage

---

<div class="post-metadata">

**Author:** ![1000001101000](https://forum.openwrt.org/user_avatar/forum.openwrt.org/1000001101000/32/22000_2.png) [@1000001101000](https://forum.openwrt.org/u/1000001101000)\
**Post date:** [June 4, 2020, 2:42am UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/3 "2020-06-04T02:42:24Z")

</div>

Great work on this!

Could you provide detail on how you set this via /dev/mem?

I'm working with some folks who are experiencing the same issue from within the debian installer and would like to add a userspace script to address this at boot until your fix can be included upstream.

---

<div class="post-metadata">

**Author:** ![danitool](https://forum.openwrt.org/letter_avatar/danitool/32/5_5575768a8748004e209b776fc1b2916d.png) [@danitool](https://forum.openwrt.org/u/danitool)\
**Post date:** [June 7, 2020, 3:40pm UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/4 "2020-06-07T15:40:58Z")

</div>

Hi **1000001101000** , in my LinkStation LS421DE, it is as simple as executing this command:

`devmem 0xd00184e0 32 0xa8a`

But it depends on your specific device. Some Marvell Armadas remap their registers to 0xf1000000, in this case the command should be:

`devmem 0xf10184e0 32 0xa8a`

It also depends on where the PHY is connected, port1 or port2. For setting to 1.8V the pins, we need to clear the some particular bits associated with the port. as you can see in my previous patch. These bits also depends on the SoC, Armada 370 or XP.

This devmem utility is the one provided by busybox. Probably it won't be available in your debian system. You may prefer to use devmem2, therefore you'll need to adapt a bit the command.

Regards

---

<div class="post-metadata">

**Author:** ![1000001101000](https://forum.openwrt.org/user_avatar/forum.openwrt.org/1000001101000/32/22000_2.png) [@1000001101000](https://forum.openwrt.org/u/1000001101000)\
**Post date:** [June 7, 2020, 4:42pm UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/5 "2020-06-07T16:42:21Z")

</div>

Thanks!

I get segfaults when trying both, I assume this means I need to disable some kernel protections for it to work. I'll look into that at some point.

Before you responded I added some printk's to your patch to try to derive the address/value. It looks like there must be some sort of offset/remap that causes a slightly different value.

```
[18.653752] phytest: Port1 Address E10B84E0 Value AAA
[18.658990] phytest: Port1 Address E10B84E0 Value A8A

```

I've run the vanilla Debian kernel on 10+ LS400 devices over the past few years and have never encountered this issue but have now heard from ~5 other people who have had this problem. A few days ago I built a kernel package with the patch applied and had one of them test but they still had the issue:  
[https://github.com/1000001101000/Debian\_on\_Buffalo/blob/master/Tools/kernel\_tools/armhf/linux-image-4.19.98\_4.19.98-2\_armhf.deb](https://github.com/1000001101000/Debian_on_Buffalo/blob/master/Tools/kernel_tools/armhf/linux-image-4.19.98_4.19.98-2_armhf.deb)

Are you aware of any other prerequisites beyond applying the patch that are required for this to work?

---

<div class="post-metadata">

**Author:** ![danitool](https://forum.openwrt.org/letter_avatar/danitool/32/5_5575768a8748004e209b776fc1b2916d.png) [@danitool](https://forum.openwrt.org/u/danitool)\
**Post date:** [June 7, 2020, 5:32pm UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/6 "2020-06-07T17:32:51Z")

</div>

> [@1000001101000](#):
>
> Are you aware of any other prerequisites beyond applying the patch that are required for this to work?

Hi, the patch was fully tested under Linux v5.4.41, where I never got any segfault. AFAIK reading the SoC documentation there is no prerequisites to set these voltages.

You can also test the fix directly on the uBoot command line:

`mw.l 0xd00184e0 0xa8a`

If it works ok from uBoot, then it should also work with devmem, or by patching the kernel.

---

<div class="post-metadata">

**Author:** ![1000001101000](https://forum.openwrt.org/user_avatar/forum.openwrt.org/1000001101000/32/22000_2.png) [@1000001101000](https://forum.openwrt.org/u/1000001101000)\
**Post date:** [August 18, 2020, 4:43pm UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/7 "2020-08-18T16:43:36Z")

</div>

We've flashed your patched uboot to a few devices and are doing some testing now. So far things are looking good and I'm looking at ways to automate flashing it for users without a serial console/etc.

I tried it out on an LS441 and unsurprisingly it didn't work (the stock uboot images are different after all).

Would you be willing to provide the patch you created for uboot? I'm hoping to use it to create a working image for the LS441 (several people are seeing the same problem with that device).

Thanks again for all your help,

---

<div class="post-metadata">

**Author:** ![danitool](https://forum.openwrt.org/letter_avatar/danitool/32/5_5575768a8748004e209b776fc1b2916d.png) [@danitool](https://forum.openwrt.org/u/danitool)\
**Post date:** [August 22, 2020, 7:56pm UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/8 "2020-08-22T19:56:09Z")

</div>

> [@1000001101000](#):
>
> ld you be willing to provide the patch you created for uboot? I'm hoping to use it to create a working

I've created a github repo with some utilities to modify the bootloader. Not really a patch but it should make the job.

> **[GitHub - danitool/ls\_a370-uboot\_tools: Tools for Linkstation Armada-370 uboot](https://github.com/danitool/ls_a370-uboot_tools)**
>
> Tools for Linkstation Armada-370 uboot. Contribute to danitool/ls\_a370-uboot\_tools development by creating an account on GitHub.

With these tools you can split the patched header of the bootloader and insert it in the LS441 uboot.

You may also try to create an UART bootloader, and see if it works before flashing the new bootloader, to prevent a brick.

I don't provide the sourcecode because the tools were compiled under a barebox SDK. And the patched header were compiled under a Synology uboot SDK. Not clean enough to make a decent repo with them.

Regards

---

<div class="post-metadata">

**Author:** ![1000001101000](https://forum.openwrt.org/user_avatar/forum.openwrt.org/1000001101000/32/22000_2.png) [@1000001101000](https://forum.openwrt.org/u/1000001101000)\
**Post date:** [August 22, 2020, 9:39pm UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/9 "2020-08-22T21:39:18Z")

</div>

Sounds reasonable.

I made a first attempt on an ls410 which was previously working with your uboot image from the ls421de page but it didn't work. Can you see where I went wrong?

```
On my PC:
./kwbimage -x -i u-boot-ls400.buffalo.updated -o .
mv payload payload_ls400_orig
mv binary.0 header_ls400_orig
./kwbimage -x -i u-boot.buffalo-1.34_voodoo -o .
mv binary.0 header_voodoo
mv payload payload_voodoo
./mvebuimg -v 1 create -b header_voodoo -o ls400_test.bin spi payload_ls400_orig

```

---

<div class="post-metadata">

**Author:** ![danitool](https://forum.openwrt.org/letter_avatar/danitool/32/5_5575768a8748004e209b776fc1b2916d.png) [@danitool](https://forum.openwrt.org/u/danitool)\
**Post date:** [January 16, 2021, 11:25am UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/10 "2021-01-16T11:25:51Z")

</div>

Hi @1000001101000, did you finally solve your problem?.

I was reviewing again the bootloader. Using another tool called _doimage_ I can recreate an "exact" copy of the original bootloader after splitting and joining again the same header and payload.

I used this tool to insert my custom header in the u-boot-1.84 and it booted correctly (using _mvebuimg_ it didn't)

For using doimage first we need to prepend 12 missing bytes to the header, and then create the new u-boot with _doimage_. In the original u-boot 1.34 bootloader there are decompression and execution addresses which doesn't exist in the original u-boot-1.84. So I used this command:

```
echo -ne \\x02\\x00\\x00\\x00\\x5B\\x00\\x00\\x00\\x68\\x00\\x00\\x00 > binary.1
cat binary.0 >> binary.1

./doimage -T flash -D 0x600000 -E 0x6A0000 -G binary.1 payload u-boot.bin

```

which produces this bootloader: [https://github.com/danitool/ls\_a370-uboot\_tools/raw/master/uboot/u-boot.buffalo-1.34\_voodoo-2](https://github.com/danitool/ls_a370-uboot_tools/raw/master/uboot/u-boot.buffalo-1.34_voodoo-2)  
Might be now this booloader is able to work in your boards?

I uploaded the new tool and instructions to the repo: [https://github.com/danitool/ls\_a370-uboot\_tools](https://github.com/danitool/ls_a370-uboot_tools)

You can use the u-boot 1.84, but there is something really wrong in this bootloader concerning to the eth PHY initialization, and the voltage fix isn't enough for a stable ethernet connection.

Regards

---

<div class="post-metadata">

**Author:** ![1000001101000](https://forum.openwrt.org/user_avatar/forum.openwrt.org/1000001101000/32/22000_2.png) [@1000001101000](https://forum.openwrt.org/u/1000001101000)\
**Post date:** [September 28, 2021, 4:08pm UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/11 "2021-09-28T16:08:19Z")

</div>

Sorry, I don't think I ever replied to this. My winding path of projects seems to be making its way back to the LS400. I'm hoping to give this a try in the near future.

I'm also looking forward to trying the other performance stuff you've been working on.

Thanks again!

---

<div class="post-metadata">

**Author:** ![thirstyice](https://forum.openwrt.org/user_avatar/forum.openwrt.org/thirstyice/32/54328_2.png) [@thirstyice](https://forum.openwrt.org/u/thirstyice)\
**Post date:** [May 26, 2022, 11:09pm UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/12 "2022-05-26T23:09:48Z")

</div>

Just installed openWrt on a LS421DE, I think I'm running into this problem. Is there an easy solution found yet?

---

<div class="post-metadata">

**Author:** ![1000001101000](https://forum.openwrt.org/user_avatar/forum.openwrt.org/1000001101000/32/22000_2.png) [@1000001101000](https://forum.openwrt.org/u/1000001101000)\
**Post date:** [May 26, 2022, 11:53pm UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/13 "2022-05-26T23:53:37Z")

</div>

I created a boot image at one point that applied the custom NAND image automatically, it olny seemed to work for about 75% of folks who tried it though. I've got another solution I've been working on which avoids reflashing or using custom kernels but it doesn't seem to work for my LS441DE. I'm starting to worry there's a different problem for the LS441.

Would someone with an affected LS421 be interested in trading for an unaffected LS421? I'm still looking for a solution that I can include in my Debian installer and could use one to test with.

---

<div class="post-metadata">

**Author:** ![thirstyice](https://forum.openwrt.org/user_avatar/forum.openwrt.org/thirstyice/32/54328_2.png) [@thirstyice](https://forum.openwrt.org/u/thirstyice)\
**Post date:** [May 27, 2022, 1:05am UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/14 "2022-05-27T01:05:18Z")

</div>

I'd be down to trade. I was trying to actually set mine up as a nas when I ran into this problem, and it would save me from having to figure out how to patch the kernel.

---

<div class="post-metadata">

**Author:** ![1000001101000](https://forum.openwrt.org/user_avatar/forum.openwrt.org/1000001101000/32/22000_2.png) [@1000001101000](https://forum.openwrt.org/u/1000001101000)\
**Post date:** [May 27, 2022, 2:13am UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/15 "2022-05-27T02:13:23Z")

</div>

DM me over on discord, hopefully we can work something out: [https://discord.gg/zkVWUDgA](https://discord.gg/zkVWUDgA)

---

<div class="post-metadata">

**Author:** ![Kosty7777](https://forum.openwrt.org/letter_avatar/kosty7777/32/5_5575768a8748004e209b776fc1b2916d.png) [@Kosty7777](https://forum.openwrt.org/u/Kosty7777)\
**Post date:** [June 12, 2023, 8:56am UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/16 "2023-06-12T08:56:52Z")

</div>

Hello, please help me to apply this patch. Tried to use manual with QUILT but there no QUILT in OpenWRT build for LS421DE.

---

<div class="post-metadata">

**Author:** ![danitool](https://forum.openwrt.org/letter_avatar/danitool/32/5_5575768a8748004e209b776fc1b2916d.png) [@danitool](https://forum.openwrt.org/u/danitool)\
**Post date:** [June 12, 2023, 9:42am UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/17 "2023-06-12T09:42:46Z")

</div>

The patch probably can't be applied with current firmwares. But it's here as a reference only. You probably may prefer to use devmem to fix this issue:

`devmem 0xd00184e0 32 0xa8a`

The result is exactly the same. But first you need to compile OpenWrt with /dev/mem enabled in kernel and the utility devmem from busybox.

---

<div class="post-metadata">

**Author:** ![Kosty7777](https://forum.openwrt.org/letter_avatar/kosty7777/32/5_5575768a8748004e209b776fc1b2916d.png) [@Kosty7777](https://forum.openwrt.org/u/Kosty7777)\
**Post date:** [June 12, 2023, 10:12am UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/18 "2023-06-12T10:12:48Z")

</div>

I have no knowladge how to compile OpenWrt with /dev/mem... Maybe is there a manual how to Patching the bootloader?

---

<div class="post-metadata">

**Author:** ![danitool](https://forum.openwrt.org/letter_avatar/danitool/32/5_5575768a8748004e209b776fc1b2916d.png) [@danitool](https://forum.openwrt.org/u/danitool)\
**Post date:** [June 12, 2023, 11:04am UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/19 "2023-06-12T11:04:49Z")

</div>

![Screenshot_20230612_130339](https://forum.openwrt.org/uploads/default/original/3X/7/f/7f68a9a2a0f675d31bf132f4661a46321f172251.png)

 ![Screenshot_20230612_130215](https://forum.openwrt.org/uploads/default/original/3X/d/6/d68203f2f6b7de59a211a592a659e125c5d1ab70.png)

---

<div class="post-metadata">

**Author:** ![Kosty7777](https://forum.openwrt.org/letter_avatar/kosty7777/32/5_5575768a8748004e209b776fc1b2916d.png) [@Kosty7777](https://forum.openwrt.org/u/Kosty7777)\
**Post date:** [June 12, 2023, 10:52pm UTC](https://forum.openwrt.org/t/mvneta-help-with-a-voltage-patch/64226/20 "2023-06-12T22:52:00Z")

</div>

How could I do this for \*sysupgrade.bin?
