summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
authorwollman <wollman@FreeBSD.org>1997-01-13 21:26:53 +0000
committerwollman <wollman@FreeBSD.org>1997-01-13 21:26:53 +0000
commit19e2ac904f46e8d37d7cd3d2b1186258b4e8f73b (patch)
tree910b1426d4c193f9ebe781e273cdb61d4b1ee1fd /sys/pci
parent52ec48faa0c0c800965bfbe06fa3f8869f922d41 (diff)
downloadFreeBSD-src-19e2ac904f46e8d37d7cd3d2b1186258b4e8f73b.zip
FreeBSD-src-19e2ac904f46e8d37d7cd3d2b1186258b4e8f73b.tar.gz
Use the new if_multiaddrs list for multicast addresses rather than the
previous hackery involving struct in_ifaddr and arpcom. Get rid of the abominable multi_kludge. Update all network interfaces to use the new machanism. Distressingly few Ethernet drivers program the multicast filter properly (assuming the hardware has one, which it usually does).
Diffstat (limited to 'sys/pci')
-rw-r--r--sys/pci/if_de.c110
-rw-r--r--sys/pci/if_fxp.c20
-rw-r--r--sys/pci/if_pdq.c48
3 files changed, 79 insertions, 99 deletions
diff --git a/sys/pci/if_de.c b/sys/pci/if_de.c
index c5d7f5a..95bc095 100644
--- a/sys/pci/if_de.c
+++ b/sys/pci/if_de.c
@@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: if_de.c,v 1.55 1996/11/10 13:36:46 davidg Exp $
+ * $Id: if_de.c,v 1.56 1996/12/01 06:01:00 rgrimes Exp $
*
*/
@@ -3287,62 +3287,63 @@ tulip_addr_filter(
tulip_softc_t * const sc)
{
u_int32_t *sp = sc->tulip_setupdata;
- struct ether_multistep step;
- struct ether_multi *enm;
+ struct ifmultiaddr *ifma;
int i = 0;
+ u_char *addrp;
+ unsigned hash;
+
+ ifma = sc->tulip_if.if_multiaddrs.lh_first;
sc->tulip_flags &= ~TULIP_WANTHASH;
sc->tulip_flags |= TULIP_WANTSETUP;
sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED;
- if (sc->tulip_ac.ac_multicnt > 14) {
- unsigned hash;
- /*
- * If we have more than 14 multicasts, we have
- * go into hash perfect mode (512 bit multicast
- * hash and one perfect hardware).
- */
- bzero(sc->tulip_setupdata, sizeof(sc->tulip_setupdata));
- hash = tulip_mchash(etherbroadcastaddr);
- sp[hash >> 4] |= 1 << (hash & 0xF);
- ETHER_FIRST_MULTI(step, &sc->tulip_ac, enm);
- while (enm != NULL) {
- hash = tulip_mchash(enm->enm_addrlo);
- sp[hash >> 4] |= 1 << (hash & 0xF);
- ETHER_NEXT_MULTI(step, enm);
- }
- sc->tulip_flags |= TULIP_WANTHASH;
- sp[39] = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[0];
- sp[40] = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[1];
- sp[41] = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[2];
- } else {
- /*
- * Else can get perfect filtering for 16 addresses.
- */
- ETHER_FIRST_MULTI(step, &sc->tulip_ac, enm);
- for (; enm != NULL; i++) {
- *sp++ = ((u_int16_t *) enm->enm_addrlo)[0];
- *sp++ = ((u_int16_t *) enm->enm_addrlo)[1];
- *sp++ = ((u_int16_t *) enm->enm_addrlo)[2];
- ETHER_NEXT_MULTI(step, enm);
- }
- /*
- * Add the broadcast address.
- */
- i++;
- *sp++ = 0xFFFF;
- *sp++ = 0xFFFF;
- *sp++ = 0xFFFF;
- /*
- * Pad the rest with our hardware address
- */
- for (; i < 16; i++) {
+ for (ifma = sc->tulip_if.if_multiaddrs.lh_first; ifma;
+ ifma = ifma->ifma_link.le_next) {
+ if (ifma->ifma_addr->sa_family != AF_LINK)
+ continue;
+ if (i > 14)
+ goto musthash;
+ addrp = LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
+ *sp++ = ((u_int16_t *) addrp)[0];
+ *sp++ = ((u_int16_t *) addrp)[1];
+ *sp++ = ((u_int16_t *) addrp)[2];
+ i++;
+ }
+ /*
+ * Add the broadcast address.
+ */
+ i++;
+ *sp++ = 0xFFFF;
+ *sp++ = 0xFFFF;
+ *sp++ = 0xFFFF;
+ /*
+ * Pad the rest with our hardware address
+ */
+ for (; i < 16; i++) {
*sp++ = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[0];
*sp++ = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[1];
*sp++ = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[2];
- }
}
+ return;
+
+musthash:
+ bzero(sc->tulip_setupdata, sizeof(sc->tulip_setupdata));
+ hash = tulip_mchash(etherbroadcastaddr);
+ sp[hash >> 4] |= 1 << (hash & 0xF);
+ for (ifma = sc->tulip_if.if_multiaddrs.lh_first; ifma;
+ ifma = ifma->ifma_link.le_next) {
+ if (ifma->ifma_addr->sa_family != AF_LINK)
+ continue;
+
+ hash = tulip_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
+ sp[hash >> 4] |= 1 << (hash & 0xF);
+ }
+ sc->tulip_flags |= TULIP_WANTHASH;
+ sp[39] = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[0];
+ sp[40] = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[1];
+ sp[41] = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[2];
}
/*
@@ -3395,22 +3396,15 @@ tulip_ifioctl(
}
case SIOCADDMULTI:
- case SIOCDELMULTI: {
+ case SIOCDELMULTI:
/*
* Update multicast listeners
*/
- if (cmd == SIOCADDMULTI)
- error = ether_addmulti(ifr, &sc->tulip_ac);
- else
- error = ether_delmulti(ifr, &sc->tulip_ac);
-
- if (error == ENETRESET) {
- tulip_addr_filter(sc); /* reset multicast filtering */
- tulip_init(sc);
- error = 0;
- }
+ tulip_addr_filter(sc); /* reset multicast filtering */
+ tulip_init(sc);
+ error = 0;
break;
- }
+
#if defined(SIOCSIFMTU)
#if !defined(ifr_mtu)
#define ifr_mtu ifr_metric
diff --git a/sys/pci/if_fxp.c b/sys/pci/if_fxp.c
index 61cb065..eed4623 100644
--- a/sys/pci/if_fxp.c
+++ b/sys/pci/if_fxp.c
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_fxp.c,v 1.22 1996/11/18 02:45:46 davidg Exp $
+ * $Id: if_fxp.c,v 1.23 1996/12/10 07:29:50 davidg Exp $
*/
/*
@@ -1055,21 +1055,11 @@ fxp_ioctl(ifp, command, data)
case SIOCADDMULTI:
case SIOCDELMULTI:
/*
- * Update out multicast list.
+ * Multicast list has changed; set the hardware filter
+ * accordingly.
*/
- error = (command == SIOCADDMULTI) ?
- ether_addmulti(ifr, &sc->arpcom) :
- ether_delmulti(ifr, &sc->arpcom);
-
- if (error == ENETRESET) {
- /*
- * Multicast list has changed; set the hardware filter
- * accordingly.
- */
- fxp_init(sc);
-
- error = 0;
- }
+ fxp_init(sc);
+ error = 0;
break;
default:
diff --git a/sys/pci/if_pdq.c b/sys/pci/if_pdq.c
index 619d22d..3fda4f9 100644
--- a/sys/pci/if_pdq.c
+++ b/sys/pci/if_pdq.c
@@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: if_pdq.c,v 1.17 1996/09/06 23:08:53 phk Exp $
+ * $Id: if_pdq.c,v 1.18 1996/09/10 08:31:31 bde Exp $
*
*/
@@ -287,17 +287,19 @@ pdq_os_addr_fill(
size_t num_addrs)
{
pdq_softc_t *sc = (pdq_softc_t *) pdq->pdq_os_ctx;
- struct ether_multistep step;
- struct ether_multi *enm;
-
- ETHER_FIRST_MULTI(step, &sc->sc_ac, enm);
- while (enm != NULL && num_addrs > 0) {
- ((u_short *) addr->lanaddr_bytes)[0] = ((u_short *) enm->enm_addrlo)[0];
- ((u_short *) addr->lanaddr_bytes)[1] = ((u_short *) enm->enm_addrlo)[1];
- ((u_short *) addr->lanaddr_bytes)[2] = ((u_short *) enm->enm_addrlo)[2];
- ETHER_NEXT_MULTI(step, enm);
- addr++;
- num_addrs--;
+ struct ifmultiaddr *ifma;
+
+ for (ifma = sc->sc_if.if_multiaddrs.lh_first; ifma && num_addrs > 0;
+ ifma = ifma->ifma_link.le_next) {
+ char *mcaddr;
+ if (ifma->ifma_addr->sa_family != AF_LINK)
+ continue;
+ mcaddr = LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
+ ((u_short *) addr->lanaddr_bytes)[0] = ((u_short *) mcaddr)[0];
+ ((u_short *) addr->lanaddr_bytes)[1] = ((u_short *) mcaddr)[1];
+ ((u_short *) addr->lanaddr_bytes)[2] = ((u_short *) mcaddr)[2];
+ addr++;
+ num_addrs--;
}
}
@@ -366,22 +368,14 @@ pdq_ifioctl(
}
case SIOCADDMULTI:
- case SIOCDELMULTI: {
- /*
- * Update multicast listeners
- */
- if (cmd == SIOCADDMULTI)
- error = ether_addmulti((struct ifreq *)data, &sc->sc_ac);
- else
- error = ether_delmulti((struct ifreq *)data, &sc->sc_ac);
-
- if (error == ENETRESET) {
+ case SIOCDELMULTI:
+ /*
+ * Update multicast listeners
+ */
if (sc->sc_if.if_flags & IFF_RUNNING)
- pdq_run(sc->sc_pdq);
+ pdq_run(sc->sc_pdq);
error = 0;
- }
- break;
- }
+ break;
default: {
error = EINVAL;
@@ -411,6 +405,8 @@ pdq_ifattach(
ifp->if_ioctl = pdq_ifioctl;
ifp->if_output = fddi_output;
ifp->if_start = pdq_ifstart;
+#warning "Implement fddi_resolvemulti!"
+/* ifp->if_resolvemulti = ether_resolvemulti; XXX */
if_attach(ifp);
fddi_ifattach(ifp);
OpenPOWER on IntegriCloud