Banana Pi BPI-R4 Wifi 7 router board with MediaTek MT7988A (Filogic 880),4G RAM and 8G eMMC

for me both mpcie-slots are working (11300000 & 11310000) with a mt7615 card

root@bpi-r4-v11:~# lspci
0001:00:00.0 PCI bridge: MEDIATEK Corp. Device 7988 (rev 01)
0001:01:00.0 Unclassified device [0002]: MEDIATEK Corp. MT7615E 802.11ac PCI Express Wireless Network Adapter                           
root@bpi-r4-v11:~# lspci                                                                                                                    
00:00.0 PCI bridge: MEDIATEK Corp. Device 7988 (rev 01)                                                                                     
01:00.0 Unclassified device [0002]: MEDIATEK Corp. MT7615E 802.11ac PCI Express Wireless Network Adapter                                    

using 6.7-dango_2 tree from my kernel repo

i guess his cards need usb or any other data-lane to work…r4 mpcie-slots are pcie only

And again be aware to have sw4 off,else you will brick other cards (12v is only for bpi wifi card)

1 Like

Question for Banana Pi folks I am already using BPI-R3 and now want to do it the same with BPI-R4, but main line support is still unavailable from OpenWRT latest build. When shall that happen?

Also what type or form of hardware acceleration off load is available? in R4 and how much of it will be supported in software?

please give devs a bit time to do proper support…we are currently working on RSS/LRO to reach 10 Speed on the SFP, but it is not working yet, in parallel we upstreaming the currently working drivers/changes to mainline

you cannot expect bying a brandnew board to have already full software support in mainline :stuck_out_tongue:

1 Like

What you want for the BPI-R4, I’ve done with R3 → buying the R3-Board as an “enduser” in a time of an unfinished software. It was a good choice for me, because i want to work into openwrt. But I could not provide development support. I have to live with that what I get :roll_eyes:.

Consider 1 Year of waiting :melting_face:. The wifi 7 modul is not even released :upside_down_face:.

1 Like

Thanks for sharing your experience. I’m there right now, watching the latest developments for the BPI-R4 and thinking about using it as a fiber router in my new home. Debating whether I can manage the work in progress or if I’d rather buy the BPI-R3 instead (or a fritzbox fiber, but that would take all the fun and flexibility away).

Hello Norman,

I’m also very interested in the BPI-R4. And this questions → “should I buy it”, is also in my head! The answer is simple → yes, no , yes, no … :wink:

If you want to use a fibre connection, the answer is simple (for me). My provider offers max 1.000 Mbit/s bandwith and the R3’s SFP could handle 2.500 Mbit/s. Why need 10.000 Mbit/s of R4?

Answering the question for connecting this routers with a cellular modem is not easy. R3 has a USB 3.0 port but mini PCI-E (for modem) only runs with USB2.0 speed. The R4 has USB 3.2 speed? If I look on the price of an Quectel RM5… 160€ is the lowest i found (EC25 is between 30€ an 40€). For the “modem decision” the answer is clear. But does an “NO” for Quectel RM5… is a “NO” for R4?

For the R4 speaks the training period (spend for R3). I’m not sure who you are, but if you decide for the R4 you can grow with this router. Yes, at this point there is no shapshot (https://firmware-selector.openwrt.org/), no case, no wifi modul and I’m not even sure about fan … . So, this is an early start. You may will spend in addition more mony and more time for “get it run”. But if you like this cutting edge devices buy R4.

A simple mony question I’m asking to myself: will it be less expensive buying the R4 board and wifi modul together?

If you want to start with the software and not care about mechanical parts maybe buy R3. But if you want to do “special things” like solving cooling problems, using a cellular modem or some of the 26 pins, than you will have to build your own case or modyfi the common BPI case. This may speaks for R4.

I live in a small room and I’m interested in power consumption of R3 AND R4. In the last days i do noting else comparing different modes of the EC25 cellular modem and try to turn if off. In case of the wifi 7 modul I ask myself about the possibility of upgradeing the R3 with a Wifi 7 card?

I’m wishing you a clear mind on the day you make the decision! In this forum you will find smart people (not me) who may can help you. And this is why I’m hoping you decide against the Fritzbox :wink:.

2 Likes

Hi, is it possible to enable secure boot on the BPi-R4?

Basicly it should be possible as all parts (atf,uboot, Linux-Kernel) are opensource.

But you have to implement it by yourself

Thanks,

Is it possible to program keys into MT7988’s eFuses?

It is possible that r4 ethernet/switch driver does not yet support 100M,you can look with ethtool which modes the (dsa-) port supports

Mhm,but your log says it does…but not stable

hello there,

I am interested in the R4 and WIFI-7. As a newbie in Router-HW and OpenWRT I could not find an answer if it is possible to ditch my combined modem and router which has WIFI 5. (Type: CH7465LG-LC unitymedia, DOCSIS with coax cable connection, cable internet Download 150Mbit/s; Upload around 30Mbit/s ) Is it possible to add a modem into R4? (with SFP?) Will it has Bluetooth and Thread (for Smarthome-applications) ?

I have to wait for the Wifi-7 Board anyway until I start with it. Thanks for your input.

Hey everyone, I created a dirty patch adding multiple ppe support, I currently lake the equipment to test if everything works as it should. If anyone wants to give it a try take it from here

2 Likes

I don’t think so unless you can obtain MT7988 reference manual. You need to access specify register in order to write efuse.

The mt7988 developer datasheet is in bpis wiki page (2 parts) but have not looked if efuse is described there too

1 Like

@zuowei8 I can generate the image with no changes. But it seems the wireless drivers are not included, and they are usually part of the feeds patches. If I select mt7915 module it fails to build.

Can you share the steps which you used to configure the mtk-opewrt-feeds which you used as base?

I tried the steps here to build the 20240112 non MLO and also Filogic 880 20230630 but they all fail to build. Is there a special procedure to build the vendor sdk not outlined in Release.md?

Hi, I think there are more issues than not enabling third ppe. Offloading should work even with just ppe0 but it’s not working at all on r4 from @dangowrt PR

I was checking this patch and it looks like some more things are missing

The reason for PPE not working on the R4 (but working fine on MT7988 reference board) is that the R4 got 4 GiB of RAM and hence requires DMA addressing beyond 32-bit boundaries (memory starts from 0x40000000, so only up to 3 GiB [0x40000000~0xFFFFFFFF] can be addressed in 32-bits. For the Ethernet DMA I’ve already adapted some changes found in MTK SDK to support 36-bit DMA, however, something is still missing in that regard for PPE to work as well.

In the meantime, and while @LorenzoBianconi and me are working on finding a good solution for the driver in mainline Linux and OpenWrt, you can test the Ethernet performance of the R4 with NAT offloading via PPE by limiting memory e.g. to 2GB by appending mem=2048M to the bootargs U-Boot environment variable.

2 Likes

The one single thing not entirely Open Source but needed for a tight trusted platform implementation is the anti-rollback protection part of the SoC’s bootrom using the efuse, for that proprietary tools are still needed.

Thanks a lot, I will try that.

I was trying to expand on @Dale patch to include more changes besides enabling 3 ppe, but it looks like the reason was 4G RAM.

--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1620,6 +1620,8 @@ struct net_device_ops {
 	struct net_device *	(*ndo_get_peer_dev)(struct net_device *dev);
 	int                     (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx,
                                                          struct net_device_path *path);
+	int                     (*ndo_fill_receive_path)(struct net_device_path_ctx *ctx,
+							 struct net_device_path *path);
 	ktime_t			(*ndo_get_tstamp)(struct net_device *dev,
 						  const struct skb_shared_hwtstamps *hwtstamps,
 						  bool cycles);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index a84e70e..a122e50 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -2306,7 +2306,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
 		}
 
 		if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-			mtk_ppe_check_skb(eth->ppe[0], skb, hash);
+			mtk_ppe_check_skb(eth->ppe[eth->mac[mac]->ppe_idx], skb, hash);
 
 		skb_record_rx_queue(skb, 0);
 		napi_gro_receive(napi, skb);
@@ -3512,6 +3512,15 @@ static int mtk_open(struct net_device *dev)
 
 		gdm_config = soc->offload_version ? soc->reg_map->gdma_to_ppe
 						  : MTK_GDMA_TO_PDMA;
+
+		if (mac->id == 2) {
+			mac->ppe_idx = 2;
+			gdm_config = MTK_GDMA_TO_PPE2;
+		} else if (mac->id == 1) {
+			mac->ppe_idx = 1;
+			gdm_config = MTK_GDMA_TO_PPE1;
+		}
+
 		mtk_gdm_config(eth, gdm_config);
 
 		napi_enable(&eth->tx_napi);
@@ -4601,6 +4610,7 @@ static const struct net_device_ops mtk_netdev_ops = {
 	.ndo_get_stats64        = mtk_get_stats64,
 	.ndo_fix_features	= mtk_fix_features,
 	.ndo_set_features	= mtk_set_features,
+	.ndo_fill_receive_path	= mtk_eth_fill_receive_path,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= mtk_poll_controller,
 #endif
@@ -4849,6 +4859,16 @@ static int mtk_sgmii_init(struct mtk_eth *eth)
 	return 0;
 }
 
+int mtk_eth_fill_receive_path(struct net_device_path_ctx *ctx,
+			      struct net_device_path *path)
+{
+	struct mtk_mac *mac = netdev_priv(ctx->dev);
+
+	path->mtk_wdma.wdma_idx = mac->ppe_idx;
+
+	return 0;
+}
+
 static int mtk_probe(struct platform_device *pdev)
 {
 	struct resource *res = NULL, *res_sram;
@@ -5078,10 +5098,12 @@ static int mtk_probe(struct platform_device *pdev)
 
 	if (eth->soc->offload_version) {
 		u32 num_ppe = mtk_is_netsys_v2_or_greater(eth) ? 2 : 1;
+		if(mtk_is_netsys_v3_or_greater(eth))
+			num_ppe = 3;
 
 		num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe);
 		for (i = 0; i < num_ppe; i++) {
-			u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
+			u32 ppe_addr = eth->soc->reg_map->ppe_base + (i == 2 ? 0xC00 : i * 0x400);
 
 			eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i);
 
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index e80f6fb..1232acf 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -125,6 +125,10 @@
 #define MTK_GDMA_TO_PDMA	0x0
 #define MTK_GDMA_DROP_ALL       0x7777
 
+#define MTK_GDMA_TO_PPE0	0x3333
+#define MTK_GDMA_TO_PPE1	0x4444
+#define MTK_GDMA_TO_PPE2	0xcccc
+
 /* GDM Egress Control Register */
 #define MTK_GDMA_EG_CTRL(x)	({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ?	\
 				   0x544 : 0x504 + (_x * 0x1000); })
@@ -1440,7 +1444,7 @@ struct mtk_eth {
 
 	struct metadata_dst		*dsa_meta[MTK_MAX_DSA_PORTS];
 
-	struct mtk_ppe			*ppe[2];
+	struct mtk_ppe			*ppe[3];
 	struct rhashtable		flow_table;
 
 	struct bpf_prog			__rcu *prog;
@@ -1465,6 +1469,7 @@ struct mtk_eth {
 struct mtk_mac {
 	int				id;
 	phy_interface_t			interface;
+	unsigned int			ppe_idx;
 	int				speed;
 	struct device_node		*of_node;
 	struct phylink			*phylink;
@@ -1625,6 +1630,8 @@ int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls,
 			 int ppe_index);
 void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list);
 void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
+int mtk_eth_fill_receive_path(struct net_device_path_ctx *ctx,
+			      struct net_device_path *path);
 
 static inline int mtk_mac2xgmii_id(struct mtk_eth *eth, int mac_id)
 {
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
index 0fc2222..c54b986 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -123,8 +123,12 @@ struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index
 	if (mtk_is_netsys_v3_or_greater(ppe->eth)) {
 		/* 64 bit for each counter */
 		u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3);
-		acct->bytes += ((u64)cnt_r1 << 32) | cnt_r0;
-		acct->packets += ((u64)cnt_r3 << 32) | cnt_r2;
+		u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
+		u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH_V2, cnt_r1);
+		u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_LOW_V2, cnt_r2);
+		u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R3_PKT_CNT_HIGH, cnt_r3);
+		acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low;
+		acct->packets += ((u64)pkt_cnt_high << 32) | pkt_cnt_low;
 	} else {
 		/* 48 bit byte counter, 40 bit packet counter */
 		u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
@@ -1061,6 +1065,11 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
 	      MTK_PPE_GLO_CFG_IP4_L4_CS_DROP |
 	      MTK_PPE_GLO_CFG_IP4_CS_DROP |
 	      MTK_PPE_GLO_CFG_FLOW_DROP_UPDATE;
+
+	if (mtk_is_netsys_v3_or_greater(ppe->eth)) {
+		val |= MTK_PPE_GLO_CFG_CS0_PIPE_EN;
+	    val |= MTK_PPE_GLO_CFG_SRH_CACHE_FIRST_EN;
+	}
 	ppe_w32(ppe, MTK_PPE_GLO_CFG, val);
 
 	ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0);
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
index 3ce088e..695653e 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
@@ -18,6 +18,8 @@
 #define MTK_PPE_GLO_CFG_UDP_LITE_EN		BIT(10)
 #define MTK_PPE_GLO_CFG_UDP_LEN_DROP		BIT(11)
 #define MTK_PPE_GLO_CFG_MCAST_ENTRIES		GNEMASK(13, 12)
+#define MTK_PPE_GLO_CFG_CS0_PIPE_EN		BIT(29)
+#define MTK_PPE_GLO_CFG_SRH_CACHE_FIRST_EN	BIT(30)
 #define MTK_PPE_GLO_CFG_BUSY			BIT(31)
 
 #define MTK_PPE_FLOW_CFG			0x204
@@ -159,11 +161,14 @@ enum {
 #define MTK_PPE_MIB_SER_R1			0x344
 #define MTK_PPE_MIB_SER_R1_PKT_CNT_LOW		GENMASK(31, 16)
 #define MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH	GENMASK(15, 0)
+#define MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH_V2	GENMASK(31, 0)
 
 #define MTK_PPE_MIB_SER_R2			0x348
 #define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH		GENMASK(23, 0)
+#define MTK_PPE_MIB_SER_R2_PKT_CNT_LOW_V2	GENMASK(31, 0)
 
 #define MTK_PPE_MIB_SER_R3			0x34c
+#define MTK_PPE_MIB_SER_R3_PKT_CNT_HIGH		GENMASK(31, 0)
 
 #define MTK_PPE_MIB_CACHE_CTL			0x350
 #define MTK_PPE_MIB_CACHE_CTL_EN		BIT(0)
--
libgit2 1.7.1

No, DOCSIS requires specialized chips that only MaxLinear and Broadcom make. You’ll at the very least need a standalone cable modem.