Banana Pi BPI-R4 Pro Wifi7 Router board with Mediatek MT7988A, 8G RAM 8G eMMC, 4x2.5G and 2x10G network port

Which connector then is the ethernet connector used for POE?

You used a BPI-5400B, not a BPI-5400? Getting Started BPI-R4Pro | BananaPi Docs ask for the version without ā€˜B’. Difference is the power structure (B=flyback, without B = forward) - whatever this means.

Best regards, kai

hi ! i can see that the full bundle with the case is now on aliexpress, but 92€ for shipping ?? is this a joke ?

or you can buy it from here:

Hi please include UK plug thx :slight_smile:

When i send this to switzerland, its still over 60 US $ for shipping. Why is this so freaking high? 200 $ item, 60 $ shipping. Its nearly 1/3 of the price only for shipping.

1 Like

Sorry, the name of the link above is incorrect. We have already changed the name to BPI-5400.

1 Like

Has anyone seen an update to OpenWRT or any other sources for a build? I have tried @frank-w Git and can’t get it to build from any branch, and the one from ā€˜Getting Started’ doesn’t allow 6gh to work in the slightest.

Just really wanting to get this router going, and I am struggling with every patch and firmware seemingly erroring out every build.

Which errors did you get? Which build environment?

This is latest and builds fine for me. Make sure doind make distclean before and not adding mtk feed. Just select the R4Ppro 8x.

I’ll try it again.

Fresh installation of Ubuntu 24.04 I’ll clone that branch and try the installation with all prerequisites. Make-menu with just the R4-Pro 8x.

Does your install open up the 6ghz band? I ran into the issue of not being able to use it because of the regdb file with the BananaPi provided firmware.

After I am done, I will report back with logs. I will save the output to a .txt file and provide a bash history if something goes wrong because I am not getting something.

Thanks for following up!

I just tried that branch @frank-w I can boot but I cannot get any trafic on any port.

From the DTS it seems to me you labelled the ports as lan0-3 but, including them in a bridge, does nothing. What am I missing?

Thank you.

Not tested wifi yet as i’'m fighting with the boards basics.

Just put port up with ip and give them an ip. I guess the uci config is wrong which i reporter in andrews PR,but i’m no openwrt expert. Phy/sfp and mux are still missing.

I did just that. Basic builed, pulled the R4Pro_Newmxl2, chose r4 pro in menu config and it fails at the same point it always does for me.

 make[3] -C package/boot/uboot-mediatek compile
    ERROR: package/boot/uboot-mediatek failed to build (build variant: mt7988_bananapi_bpi-r4-pro-8x-emmc).
make -r world: build failed. Please re-run make with -j1 V=s or V=sc for a higher verbosity level to see what's going on
make: *** [/home/openwrt-test/openwrt/include/toplevel.mk:233: world] Error 1

I forgot to use verbose and save it to text, but I will do another run here shortly.

builds for me, i guess you miss any tool for building…afair i had to install additional packages for openwrt

so, yes run make with at least V=s

I have been looking at the code and started to debug the 10g/sfp and 10g/wan mux and made some temporary changes (including debugging the mux/dsa and mxl/as21xxx

I have now the as21xxx/mxl lan ports working + the sfp lan/wan muxing between 10g ports

I also noticed @frank-w on your build that wan points to eth0, wan is on eth1 (maybe this is from the bpi-r4 config)

all of this was tested on trixie

wan muxing (removing the sfp wan module)

root@bpi-r4pro:/etc/systemd/network# [ 2365.410673] mtk_soc_eth 15100000.ethernet eth1: Link is Down
[ 2384.370638] sfp sfp2: module removed
[ 2384.428398] mtk_soc_eth 15100000.ethernet: ethernet mux: line:5383 new channel:0,sfp:0
[ 2384.436342] mtk_soc_eth 15100000.ethernet: Destroying phylink for channel 1
[ 2384.443334] mtk_soc_eth 15100000.ethernet: Created phylink for channel 0
[ 2384.450035] mtk_soc_eth 15100000.ethernet: ethernet mux: switch to channel0
[ 2384.468467] Aeonsemi AS21xxx mdio-bus:1c: Firmware Version: 1.9.1
[ 2384.563653] mtk_soc_eth 15100000.ethernet eth1: PHY [mdio-bus:1c] driver [Aeonsemi AS21xxx] (irq=POLL)
[ 2384.573010] mtk_soc_eth 15100000.ethernet eth1: configuring for phy/10gbase-r link mode
[ 2390.975253] mtk_soc_eth 15100000.ethernet eth1: Link is Up - 100Mbps/Full - flow control rx/tx

lan muxing - removing the sfp lan module

[ 2474.920529] mtk_soc_eth 15100000.ethernet eth1: PHY [i2c:sfp2:11] driver [Aquantia AQR113C] (irq=POLL)
[ 2477.874196] sfp sfp1: module removed
[ 2477.928942] net lan4: PHY already attached
[ 2478.138379] mxl862xx mdio-bus:10 lan4: configuring for phy/10gbase-r link mode
[ 2478.145841] mxl862xx mdio-bus:10: dsa mux: switch to channel1

some debug messages

[   16.791195] mxl862xx mdio-bus:10: port 8 dsa-tag-protocol="mxl862_8021q" -> using mxl862_8021q
[   16.799862] DSA: tree 0 setup: routing table
[   16.804123] DSA: tree 0 setup: cpu ports
[   16.808036] DSA: tree 0 setup: switches
[   16.811872] DSA: tree 0 setup_switches: switch 0 begin
[   16.816999] mxl862xx mdio-bus:10: dsa_switch_setup: begin
[   16.822399] mxl862xx mdio-bus:10:    Mxl862xx CPU Port 8, User Port number 5
[   17.258646] MaxLinear Ethernet MxL86252 mxl862xx_dsa-0:00: Firmware Version: 0.77 (0x004D test version)
[   17.700531] MaxLinear Ethernet MxL86252 mxl862xx_dsa-0:01: Firmware Version: 0.77 (0x004D test version)
[   18.142337] MaxLinear Ethernet MxL86252 mxl862xx_dsa-0:02: Firmware Version: 0.77 (0x004D test version)
[   18.584258] MaxLinear Ethernet MxL86252 mxl862xx_dsa-0:03: Firmware Version: 0.77 (0x004D test version)
[   19.098385] mtk_soc_eth 15100000.ethernet: ethernet mux: line:5383 new channel:0,sfp:0
[   19.106294] mtk_soc_eth 15100000.ethernet: Destroying phylink for channel 1
[   19.113273] mtk_soc_eth 15100000.ethernet: Created phylink for channel 0
[   19.119968] mtk_soc_eth 15100000.ethernet: ethernet mux: switch to channel0
[   24.599511] mxl862xx mdio-bus:10: port 8 dsa-tag-protocol="mxl862_8021q" -> using mxl862_8021q
[   24.610630] mxl862xx mdio-bus:10: mxl862xx_set_vlan_filter_limits: user_pnum:5, priv->max_vlans: 36, cpu_ingress_entries: 11, cpu_egress_entries: 74, user_ingress_entries: 77, user_egress_entries: 75
[   24.628345] mxl862xx mdio-bus:10: setup: vlan limits configured, start per-port init

.....
[   36.348744] lanbr0: port 1(lan3) entered blocking state
[   36.353986] lanbr0: port 1(lan3) entered disabled state
[   36.359274] mxl862xx mdio-bus:10 lan3: entered allmulticast mode
[   36.365279] mtk_soc_eth 15100000.ethernet eth2: entered allmulticast mode
[   36.438127] mxl862xx mdio-bus:10 lan3: entered promiscuous mode
[   36.450843] mxl862xx mdio-bus:10: mxl862xx_port_vlan_add: port:3 setting VLAN:1 with vlan_filtering disabled
[   36.478875] lanbr0: port 2(lan0) entered blocking state
[   36.484115] lanbr0: port 2(lan0) entered disabled state
[   36.489403] mxl862xx mdio-bus:10 lan0: entered allmulticast mode
[   36.556676] mxl862xx mdio-bus:10 lan0: entered promiscuous mode
[   36.567823] mxl862xx mdio-bus:10: mxl862xx_port_vlan_add: port:0 setting VLAN:1 with vlan_filtering disabled
[   36.592899] lanbr0: port 3(lan4) entered blocking state
[   36.598132] lanbr0: port 3(lan4) entered disabled state
[   36.603391] mxl862xx mdio-bus:10 lan4: entered allmulticast mode
[   36.675251] mxl862xx mdio-bus:10 lan4: entered promiscuous mode
[   36.686204] mxl862xx mdio-bus:10: mxl862xx_port_vlan_add: port:12 setting VLAN:1 with vlan_filtering disabled

hopefully this useful for anyone working in stabilising the r4-pro

as a background i brought the aseon 1.9.1 patch and fix it to the 6.19 kernel

1 Like

Afair phy/sfp behind mxl mux were working for me.i had only trouble with phylink on mtk mac which i had changed compared to sdk.

I already created branch with 1.9.2 driver which seems to work on quick test,but link-up takes ~40s. Only tested 1G speed yet.

I had disabled systemd network files on my system. That maybr the wan-issue…r4pro has no port labeled wan…wan-combo is eth1 because mac-mux.

The 1.9.2 has been reverted on mediatek feed, just fyi

1 Like

Mhm,indeed, the same day i found some time to add driver to my repo :frowning: maybe it is the link down/up issue i experienced (only looked on r4pro where is only 40s to get a link up…possibly the other side - my switch - was flapping)

@rmandrad which issues did you faced with my 6.18-main tree (i guess your patch is based on it)? Can you split patches into dts, dsmux and mtkmux? Then i cherry-pick it to my repo

i went straight to your 6.19-rc branch i haven’t touched the 6.18-main for this piece.

let me have a look at splitting … i will keep the debugging messages

here’s the branch with the commits split

on another aspect - i am unsure if anyone has problems while rebooting or doing a uboot reset using the sdmmc.

I always was having a PANIC related to the TF-A BL2 MMC path

ERROR:   FIP boot source initialization failed with -2
PANIC at PC : 0x0000000000205db8

I created this mtk-atf patch

diff --git a/plat/mediatek/apsoc_common/bl2/bl2_boot_mmc.c b/plat/mediatek/apsoc_common/bl2/bl2_boot_mmc.c
index 3ef0fe526b5..d1cad592efb 100644
--- a/plat/mediatek/apsoc_common/bl2/bl2_boot_mmc.c
+++ b/plat/mediatek/apsoc_common/bl2/bl2_boot_mmc.c
@@ -112,21 +112,31 @@ static size_t mmc_uda_read_blocks(int lba, uintptr_t buf, size_t size)
 static int mtk_mmc_gpt_init(void)
 {
 	int ret;
+	int attempt;
 
 	static bool gpt_ready = false;
 
 	if (gpt_ready)
 		return 0;
 
-	ret = gpt_partition_init();
-	if (ret != 0) {
-		ERROR("Failed to initialize GPT partitions\n");
-		return -ENOENT;
-	}
+	for (attempt = 0; attempt < 3; attempt++) {
+		ret = gpt_partition_init();
+		if (ret == 0) {
+			gpt_ready = true;
+			return 0;
+		}
 
-	gpt_ready = true;
+		WARN("GPT init attempt %d failed (%d)\n", attempt + 1, ret);
 
-	return 0;
+		ret = mtk_plat_mmc_setup(&num_sectors);
+		if (ret) {
+			ERROR("Failed to reinitialize MMC (%d)\n", ret);
+			return ret;
+		}
+	}
+
+	ERROR("Failed to initialize GPT partitions (%d)\n", ret);
+	return ret;
 }
 #endif
 
diff --git a/plat/mediatek/apsoc_common/drivers/mmc/mtk-sd.c b/plat/mediatek/apsoc_common/drivers/mmc/mtk-sd.c
index f2068ad090a..bd016de8ec2 100644
--- a/plat/mediatek/apsoc_common/drivers/mmc/mtk-sd.c
+++ b/plat/mediatek/apsoc_common/drivers/mmc/mtk-sd.c
@@ -174,7 +174,7 @@
  * greater than 25MHz
  */
 #define INIT_CLK_FREQ			1000000
-#define DEFAULT_CLK_FREQ		25000000
+#define DEFAULT_CLK_FREQ		MMC_BOOT_CLK_RATE
 
 #define CMD_INTS_MASK	\
 	(MSDC_INT_CMDRDY | MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO)
@@ -974,10 +974,10 @@ static const struct mmc_ops mtk_mmc_ops = {
 	.card_busy = msdc_card_busy,
 };
 
-void mtk_mmc_init(uintptr_t reg_base,  uintptr_t top_reg_base,
-		  const struct msdc_compatible *compat,
-		  uint32_t src_clk, enum mmc_device_type type,
-		  uint32_t bus_width)
+int mtk_mmc_init(uintptr_t reg_base, uintptr_t top_reg_base,
+		 const struct msdc_compatible *compat,
+		 uint32_t src_clk, enum mmc_device_type type,
+		 uint32_t bus_width)
 {
 	struct msdc_host *host = &_host;
 
@@ -991,8 +991,8 @@ void mtk_mmc_init(uintptr_t reg_base,  uintptr_t top_reg_base,
 
 	mtk_mmc_device_info.mmc_dev_type = type;
 
-	mmc_init(&mtk_mmc_ops, DEFAULT_CLK_FREQ, bus_width, 0,
-		 &mtk_mmc_device_info);
+	return mmc_init(&mtk_mmc_ops, DEFAULT_CLK_FREQ, bus_width, 0,
+			&mtk_mmc_device_info);
 }
 
 uint64_t mtk_mmc_device_size(void)
diff --git a/plat/mediatek/apsoc_common/drivers/mmc/mtk-sd.h b/plat/mediatek/apsoc_common/drivers/mmc/mtk-sd.h
index 9be89d82235..c8e05182532 100644
--- a/plat/mediatek/apsoc_common/drivers/mmc/mtk-sd.h
+++ b/plat/mediatek/apsoc_common/drivers/mmc/mtk-sd.h
@@ -14,10 +14,10 @@ struct msdc_compatible {
 	uint32_t latch_ck;
 };
 
-void mtk_mmc_init(uintptr_t reg_base, uintptr_t top_reg_base,
-		  const struct msdc_compatible *compat,
-		  uint32_t src_clk, enum mmc_device_type type,
-		  uint32_t bus_width);
+int mtk_mmc_init(uintptr_t reg_base, uintptr_t top_reg_base,
+		 const struct msdc_compatible *compat,
+		 uint32_t src_clk, enum mmc_device_type type,
+		 uint32_t bus_width);
 
 uint64_t mtk_mmc_device_size(void);
 uint32_t mtk_mmc_block_count(void);
diff --git a/plat/mediatek/mt7622/bl2/bl2_dev_mmc.c b/plat/mediatek/mt7622/bl2/bl2_dev_mmc.c
index 5ab357ddf7e..d0f6032315e 100644
--- a/plat/mediatek/mt7622/bl2/bl2_dev_mmc.c
+++ b/plat/mediatek/mt7622/bl2/bl2_dev_mmc.c
@@ -79,13 +79,16 @@ static const struct mt7622_msdc_conf {
 int mtk_plat_mmc_setup(uint32_t *num_sectors)
 {
 	const struct mt7622_msdc_conf *conf = &mt7622_msdc[MSDC_INDEX];
+	int ret;
 	uint32_t i;
 
 	for (i = 0; i < conf->pinmux->count; i++)
 		mtk_set_pin_mode(conf->pinmux->pins[i], conf->pinmux->mux);
 
-	mtk_mmc_init(conf->base, 0, conf->dev_comp, conf->src_clk, conf->type,
-		     conf->bus_width);
+	ret = mtk_mmc_init(conf->base, 0, conf->dev_comp, conf->src_clk, conf->type,
+			   conf->bus_width);
+	if (ret)
+		return ret;
 
 	if (num_sectors)
 		*num_sectors = mtk_mmc_block_count();
diff --git a/plat/mediatek/mt7981/bl2/bl2_dev_mmc.c b/plat/mediatek/mt7981/bl2/bl2_dev_mmc.c
index 74471b20261..f31caf5d0be 100644
--- a/plat/mediatek/mt7981/bl2/bl2_dev_mmc.c
+++ b/plat/mediatek/mt7981/bl2/bl2_dev_mmc.c
@@ -116,6 +116,7 @@ static void mmc_gpio_setup(void)
 int mtk_plat_mmc_setup(uint32_t *num_sectors)
 {
 	const struct mt7981_msdc_conf *conf = &mt7981_msdc[MSDC_INDEX];
+	int ret;
 	uint32_t i;
 
 	for (i = 0; i < conf->pinmux->count; i++) {
@@ -125,8 +126,10 @@ int mtk_plat_mmc_setup(uint32_t *num_sectors)
 
 	mmc_gpio_setup();
 
-	mtk_mmc_init(conf->base, conf->top_base, conf->dev_comp,
-		     conf->src_clk, conf->type, conf->bus_width);
+	ret = mtk_mmc_init(conf->base, conf->top_base, conf->dev_comp,
+			   conf->src_clk, conf->type, conf->bus_width);
+	if (ret)
+		return ret;
 
 	if (num_sectors)
 		*num_sectors = mtk_mmc_block_count();
diff --git a/plat/mediatek/mt7986/bl2/bl2_dev_mmc.c b/plat/mediatek/mt7986/bl2/bl2_dev_mmc.c
index fec558a8265..1a8b0ce6ff1 100644
--- a/plat/mediatek/mt7986/bl2/bl2_dev_mmc.c
+++ b/plat/mediatek/mt7986/bl2/bl2_dev_mmc.c
@@ -172,11 +172,14 @@ static void mmc_gpio_setup(void)
 int mtk_plat_mmc_setup(uint32_t *num_sectors)
 {
 	const struct mt7986_msdc_conf *conf = &mt7986_msdc[MSDC_INDEX];
+	int ret;
 
 	mmc_gpio_setup();
 
-	mtk_mmc_init(conf->base, conf->top_base, conf->dev_comp,
-		     conf->src_clk, conf->type, conf->bus_width);
+	ret = mtk_mmc_init(conf->base, conf->top_base, conf->dev_comp,
+			   conf->src_clk, conf->type, conf->bus_width);
+	if (ret)
+		return ret;
 
 	if (num_sectors)
 		*num_sectors = mtk_mmc_block_count();
diff --git a/plat/mediatek/mt7987/bl2/bl2_dev_mmc.c b/plat/mediatek/mt7987/bl2/bl2_dev_mmc.c
index 2faededfcb0..abf7a7417a3 100644
--- a/plat/mediatek/mt7987/bl2/bl2_dev_mmc.c
+++ b/plat/mediatek/mt7987/bl2/bl2_dev_mmc.c
@@ -147,6 +147,7 @@ static void mmc_gpio_setup(void)
 int mtk_plat_mmc_setup(uint32_t *num_sectors)
 {
 	const struct mt7987_msdc_conf *conf = &mt7987_msdc[MSDC_INDEX];
+	int ret;
 	uint32_t i;
 
 	for (i = 0; i < conf->pinmux->count; i++) {
@@ -156,8 +157,10 @@ int mtk_plat_mmc_setup(uint32_t *num_sectors)
 
 	mmc_gpio_setup();
 
-	mtk_mmc_init(conf->base, conf->top_base, conf->dev_comp, conf->src_clk,
-		     conf->type, conf->bus_width);
+	ret = mtk_mmc_init(conf->base, conf->top_base, conf->dev_comp, conf->src_clk,
+			   conf->type, conf->bus_width);
+	if (ret)
+		return ret;
 
 	if (num_sectors)
 		*num_sectors = mtk_mmc_block_count();
diff --git a/plat/mediatek/mt7988/bl2/bl2_dev_mmc.c b/plat/mediatek/mt7988/bl2/bl2_dev_mmc.c
index 0744cbfe3b6..0ef40647fb3 100644
--- a/plat/mediatek/mt7988/bl2/bl2_dev_mmc.c
+++ b/plat/mediatek/mt7988/bl2/bl2_dev_mmc.c
@@ -148,6 +148,7 @@ static void mmc_gpio_setup(void)
 int mtk_plat_mmc_setup(uint32_t *num_sectors)
 {
 	const struct mt7988_msdc_conf *conf = &mt7988_msdc[MSDC_INDEX];
+	int ret;
 	uint32_t i;
 
 	for (i = 0; i < conf->pinmux->count; i++) {
@@ -157,8 +158,10 @@ int mtk_plat_mmc_setup(uint32_t *num_sectors)
 
 	mmc_gpio_setup();
 
-	mtk_mmc_init(conf->base, conf->top_base, conf->dev_comp, conf->src_clk,
-		     conf->type, conf->bus_width);
+	ret = mtk_mmc_init(conf->base, conf->top_base, conf->dev_comp, conf->src_clk,
+			   conf->type, conf->bus_width);
+	if (ret)
+		return ret;
 
 	if (num_sectors)
 		*num_sectors = mtk_mmc_block_count();