shithub: riscv

Download patch

ref: 34e7b54c139826b55713702910a1280e6651df60
parent: 2c8181eed790fb5bc31c348f3988fd462601a0c3
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Dec 19 14:41:07 EST 2023

ethervirtio: make multicast work (thanks Arne)

> this fixes multicast on hypervisors without a command queue
> for the ethernet interface, like OpenBSD.
> Right now the driver does not install a multicast function when
> no command queue is ava> ilable.
> This breaks multicast because the network stack errors out in
> netif.c:netmulti.
> To fix this, move the check for the queue to the multicast and
> promiscuous functions and install those functions unconditionally.

--- a/sys/src/9/pc/ethervirtio.c
+++ b/sys/src/9/pc/ethervirtio.c
@@ -479,8 +479,12 @@
 promiscuous(void *arg, int on)
 {
 	Ether *edev = arg;
+	Ctlr *ctlr = edev->ctlr;
 	uchar b[1];
 
+	if((ctlr->feat & (Fctrlvq|Fctrlrx)) != (Fctrlvq|Fctrlrx))
+		return;
+
 	b[0] = on != 0;
 	vctlcmd(edev, CtrlRx, CmdPromisc, b, sizeof(b));
 }
@@ -489,8 +493,12 @@
 multicast(void *arg, uchar*, int)
 {
 	Ether *edev = arg;
+	Ctlr *ctlr = edev->ctlr;
 	uchar b[1];
 
+	if((ctlr->feat & (Fctrlvq|Fctrlrx)) != (Fctrlvq|Fctrlrx))
+		return;
+
 	b[0] = edev->nmaddr > 0;
 	vctlcmd(edev, CtrlRx, CmdAllmulti, b, sizeof(b));
 }
@@ -671,11 +679,8 @@
 	edev->attach = attach;
 	edev->shutdown = shutdown;
 	edev->ifstat = ifstat;
-
-	if((ctlr->feat & (Fctrlvq|Fctrlrx)) == (Fctrlvq|Fctrlrx)){
-		edev->multicast = multicast;
-		edev->promiscuous = promiscuous;
-	}
+	edev->multicast = multicast;
+	edev->promiscuous = promiscuous;
 
 	pcisetbme(ctlr->pcidev);
 	intrenable(edev->irq, interrupt, edev, edev->tbdf, edev->name);
--- a/sys/src/9/port/ethervirtio10.c
+++ b/sys/src/9/port/ethervirtio10.c
@@ -528,8 +528,12 @@
 promiscuous(void *arg, int on)
 {
 	Ether *edev = arg;
+	Ctlr *ctlr = edev->ctlr;
 	uchar b[1];
 
+	if((ctlr->feat[0] & (Fctrlvq|Fctrlrx)) != (Fctrlvq|Fctrlrx))
+		return;
+
 	b[0] = on != 0;
 	vctlcmd(edev, CtrlRx, CmdPromisc, b, sizeof(b));
 }
@@ -538,8 +542,12 @@
 multicast(void *arg, uchar*, int)
 {
 	Ether *edev = arg;
+	Ctlr *ctlr = edev->ctlr;
 	uchar b[1];
 
+    if((ctlr->feat[0] & (Fctrlvq|Fctrlrx)) != (Fctrlvq|Fctrlrx))
+		return;
+
 	b[0] = edev->nmaddr > 0;
 	vctlcmd(edev, CtrlRx, CmdAllmulti, b, sizeof(b));
 }
@@ -774,11 +782,9 @@
 	edev->attach = attach;
 	edev->shutdown = shutdown;
 	edev->ifstat = ifstat;
+	edev->multicast = multicast;
+	edev->promiscuous = promiscuous;
 
-	if((ctlr->feat[0] & (Fctrlvq|Fctrlrx)) == (Fctrlvq|Fctrlrx)){
-		edev->multicast = multicast;
-		edev->promiscuous = promiscuous;
-	}
 
 	pcisetbme(ctlr->pcidev);
 	intrenable(edev->irq, interrupt, edev, edev->tbdf, edev->name);