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);