summaryrefslogtreecommitdiffstats
path: root/sys/mips/cavium
diff options
context:
space:
mode:
authorjmallett <jmallett@FreeBSD.org>2012-03-11 00:34:14 +0000
committerjmallett <jmallett@FreeBSD.org>2012-03-11 00:34:14 +0000
commit97844c8c7b95012f8ff5a062f03aef36be8f4eab (patch)
treef5a657c8abdab9208befe5d949114664d686f774 /sys/mips/cavium
parent51ea18200982845836e145b9c1446ba0a2f0eea3 (diff)
downloadFreeBSD-src-97844c8c7b95012f8ff5a062f03aef36be8f4eab.zip
FreeBSD-src-97844c8c7b95012f8ff5a062f03aef36be8f4eab.tar.gz
Fix promiscuous mode with if_octm:
o) The MAC set must occur before the multicast list is set up as the former will enable the CAM unconditionally, while promiscuous mode disables it, so if promiscuous mode is to be set this must occur after the MAC is programmed. o) The multicast list must be set up unconditionally as even if flags have not changed, if the interface has gone through a reinitialization, the state of the CAM as changed by the MAC initialization could be incorrect. o) Call octm_init when flags change, even if the interface is already running.
Diffstat (limited to 'sys/mips/cavium')
-rw-r--r--sys/mips/cavium/if_octm.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/sys/mips/cavium/if_octm.c b/sys/mips/cavium/if_octm.c
index 3809404..1b3c68f 100644
--- a/sys/mips/cavium/if_octm.c
+++ b/sys/mips/cavium/if_octm.c
@@ -298,19 +298,27 @@ octm_init(void *arg)
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
}
- if (((ifp->if_flags ^ sc->sc_flags) & (IFF_ALLMULTI | IFF_MULTICAST | IFF_PROMISC)) != 0) {
- flags = 0;
- if ((ifp->if_flags & IFF_ALLMULTI) != 0)
- flags |= CVMX_IFF_ALLMULTI;
- if ((ifp->if_flags & IFF_PROMISC) != 0)
- flags |= CVMX_IFF_PROMISC;
- cvmx_mgmt_port_set_multicast_list(sc->sc_port, flags);
- }
-
+ /*
+ * NB:
+ * MAC must be set before allmulti and promisc below, as
+ * cvmx_mgmt_port_set_mac will always enable the CAM, and turning on
+ * promiscuous mode only works with the CAM disabled.
+ */
mac = 0;
memcpy((u_int8_t *)&mac + 2, IF_LLADDR(ifp), 6);
cvmx_mgmt_port_set_mac(sc->sc_port, mac);
+ /*
+ * This is done unconditionally, rather than only if sc_flags have
+ * changed because of set_mac's effect on the CAM noted above.
+ */
+ flags = 0;
+ if ((ifp->if_flags & IFF_ALLMULTI) != 0)
+ flags |= CVMX_IFF_ALLMULTI;
+ if ((ifp->if_flags & IFF_PROMISC) != 0)
+ flags |= CVMX_IFF_PROMISC;
+ cvmx_mgmt_port_set_multicast_list(sc->sc_port, flags);
+
/* XXX link state? */
if ((ifp->if_flags & IFF_UP) != 0)
@@ -444,8 +452,7 @@ octm_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
if (ifp->if_flags == sc->sc_flags)
return (0);
if ((ifp->if_flags & IFF_UP) != 0) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- octm_init(sc);
+ octm_init(sc);
} else {
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
cvmx_mgmt_port_disable(sc->sc_port);
OpenPOWER on IntegriCloud