summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorJonathan Matthew <jmatthew@cvs.openbsd.org>2019-06-14 07:02:56 +0000
committerJonathan Matthew <jmatthew@cvs.openbsd.org>2019-06-14 07:02:56 +0000
commit7744e1d4236f8a0fafa460737df04339d9cdc92b (patch)
tree3ebf94fe3f06b8805876bca984c18d75e030d2ef /sys/dev/pci
parent5bb3700dd16c733316a028a1c043420c54184a95 (diff)
Only add and remove flow table entries for multicast while the interface is
up, and re-add flow table entries for all existing multicast groups when bringing the interface up.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/if_mcx.c43
1 files changed, 28 insertions, 15 deletions
diff --git a/sys/dev/pci/if_mcx.c b/sys/dev/pci/if_mcx.c
index 0d46eb4fb64..13fb381b912 100644
--- a/sys/dev/pci/if_mcx.c
+++ b/sys/dev/pci/if_mcx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_mcx.c,v 1.29 2019/06/14 03:40:55 jmatthew Exp $ */
+/* $OpenBSD: if_mcx.c,v 1.30 2019/06/14 07:02:55 jmatthew Exp $ */
/*
* Copyright (c) 2017 David Gwynne <dlg@openbsd.org>
@@ -1958,7 +1958,7 @@ struct mcx_softc {
int sc_flow_group_start[MCX_NUM_FLOW_GROUPS];
int sc_promisc_flow_enabled;
int sc_allmulti_flow_enabled;
- int sc_first_mcast_flow_entry;
+ int sc_mcast_flow_base;
int sc_extra_mcast;
uint8_t sc_mcast_flows[MCX_NUM_MCAST_FLOWS][ETHER_ADDR_LEN];
@@ -2372,6 +2372,8 @@ mcx_attach(struct device *parent, struct device *self, void *aux)
sc->sc_flow_group_size[i] = 0;
sc->sc_flow_group_start[i] = 0;
}
+ sc->sc_extra_mcast = 0;
+ memset(sc->sc_mcast_flows, 0, sizeof(sc->sc_mcast_flows));
return;
teardown:
@@ -4963,8 +4965,8 @@ mcx_delete_flow_table_entry(struct mcx_softc *sc, int group, int index)
out = mcx_cmdq_out(cqe);
if (out->cmd_status != MCX_CQ_STATUS_OK) {
- printf("%s: delete flow table entry %d failed (%x, %x)\n",
- DEVNAME(sc), index, out->cmd_status,
+ printf("%s: delete flow table entry %d:%d failed (%x, %x)\n",
+ DEVNAME(sc), group, index, out->cmd_status,
betoh32(out->cmd_syndrome));
error = -1;
goto free;
@@ -5970,9 +5972,16 @@ mcx_up(struct mcx_softc *sc)
start++;
/* multicast entries go after that */
- sc->sc_first_mcast_flow_entry = start;
- sc->sc_extra_mcast = 0;
- memset(sc->sc_mcast_flows, 0, sizeof(sc->sc_mcast_flows));
+ sc->sc_mcast_flow_base = start;
+
+ /* re-add any existing multicast flows */
+ for (i = 0; i < MCX_NUM_MCAST_FLOWS; i++) {
+ if (sc->sc_mcast_flows[i][0] != 0) {
+ mcx_set_flow_table_entry(sc, MCX_FLOW_GROUP_MAC,
+ sc->sc_mcast_flow_base + i,
+ sc->sc_mcast_flows[i]);
+ }
+ }
if (mcx_set_flow_table_root(sc) != 0)
goto down;
@@ -6032,7 +6041,7 @@ mcx_down(struct mcx_softc *sc)
for (i = 0; i < MCX_NUM_MCAST_FLOWS; i++) {
if (sc->sc_mcast_flows[i][0] != 0) {
mcx_delete_flow_table_entry(sc, MCX_FLOW_GROUP_MAC,
- sc->sc_first_mcast_flow_entry + i);
+ sc->sc_mcast_flow_base + i);
}
}
@@ -6125,10 +6134,12 @@ mcx_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
if (sc->sc_mcast_flows[i][0] == 0) {
memcpy(sc->sc_mcast_flows[i], addrlo,
ETHER_ADDR_LEN);
- mcx_set_flow_table_entry(sc,
- MCX_FLOW_GROUP_MAC,
- sc->sc_first_mcast_flow_entry + i,
- sc->sc_mcast_flows[i]);
+ if (ISSET(ifp->if_flags, IFF_RUNNING)) {
+ mcx_set_flow_table_entry(sc,
+ MCX_FLOW_GROUP_MAC,
+ sc->sc_mcast_flow_base + i,
+ sc->sc_mcast_flows[i]);
+ }
break;
}
}
@@ -6157,9 +6168,11 @@ mcx_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
for (i = 0; i < MCX_NUM_MCAST_FLOWS; i++) {
if (memcmp(sc->sc_mcast_flows[i], addrlo,
ETHER_ADDR_LEN) == 0) {
- mcx_delete_flow_table_entry(sc,
- MCX_FLOW_GROUP_MAC,
- sc->sc_first_mcast_flow_entry + i);
+ if (ISSET(ifp->if_flags, IFF_RUNNING)) {
+ mcx_delete_flow_table_entry(sc,
+ MCX_FLOW_GROUP_MAC,
+ sc->sc_mcast_flow_base + i);
+ }
sc->sc_mcast_flows[i][0] = 0;
break;
}