Various fixes to make de(4) not panic after ru@'s IF_LLADDR() changes:

- Don't call tulip_addr_filter() to reset the RX address filter in
  tulip_reset() since that gets called before ether_ifattach().  Just
  call it in tulip_init_locked().
- Use be16dec() and le16dec() to parse MAC addresses when programming
  the RX filter.
- Let ether_ioctl() handle SIOCSIFMTU since we were doing the exact same
  thing with the added bonus that we leaked the driver lock if the MTU
  was > ETHERMTU in the homerolled version.  This part will be MFC'd.

Clue from:	wpaul (1)
Stolen from:	marcel (2 via patch for dc(4))
MFC after:	1 week
This commit is contained in:
John Baldwin 2005-11-21 21:50:07 +00:00
parent 1fbc4b9d85
commit f5e19c7342
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=152666
4 changed files with 44 additions and 60 deletions

View File

@ -3084,9 +3084,9 @@ tulip_addr_filter(tulip_softc_t * const sc)
hash = tulip_mchash(IF_LLADDR(ifp));
sp[hash >> 4] |= htole32(1 << (hash & 0xF));
} else {
sp[39] = TULIP_SP_MAC(((u_int16_t *)IF_LLADDR(ifp))[0]);
sp[40] = TULIP_SP_MAC(((u_int16_t *)IF_LLADDR(ifp))[1]);
sp[41] = TULIP_SP_MAC(((u_int16_t *)IF_LLADDR(ifp))[2]);
sp[39] = TULIP_SP_MAC((u_int16_t *)IF_LLADDR(ifp) + 0);
sp[40] = TULIP_SP_MAC((u_int16_t *)IF_LLADDR(ifp) + 1);
sp[41] = TULIP_SP_MAC((u_int16_t *)IF_LLADDR(ifp) + 2);
}
}
}
@ -3101,26 +3101,32 @@ tulip_addr_filter(tulip_softc_t * const sc)
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
addrp = LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
*sp++ = TULIP_SP_MAC(((u_int16_t *)addrp)[0]);
*sp++ = TULIP_SP_MAC(((u_int16_t *)addrp)[1]);
*sp++ = TULIP_SP_MAC(((u_int16_t *)addrp)[2]);
*sp++ = TULIP_SP_MAC((u_int16_t *)addrp + 0);
*sp++ = TULIP_SP_MAC((u_int16_t *)addrp + 1);
*sp++ = TULIP_SP_MAC((u_int16_t *)addrp + 2);
idx++;
}
/*
* Add the broadcast address.
*/
idx++;
*sp++ = TULIP_SP_MAC(0xFFFF);
*sp++ = TULIP_SP_MAC(0xFFFF);
*sp++ = TULIP_SP_MAC(0xFFFF);
#if BYTE_ORDER == BIG_ENDIAN
*sp++ = 0xFFFF << 16;
*sp++ = 0xFFFF << 16;
*sp++ = 0xFFFF << 16;
#else
*sp++ = 0xFFFF;
*sp++ = 0xFFFF;
*sp++ = 0xFFFF;
#endif
}
/*
* Pad the rest with our hardware address
*/
for (; idx < 16; idx++) {
*sp++ = TULIP_SP_MAC(((u_int16_t *)IF_LLADDR(ifp))[0]);
*sp++ = TULIP_SP_MAC(((u_int16_t *)IF_LLADDR(ifp))[1]);
*sp++ = TULIP_SP_MAC(((u_int16_t *)IF_LLADDR(ifp))[2]);
*sp++ = TULIP_SP_MAC((u_int16_t *)IF_LLADDR(ifp) + 0);
*sp++ = TULIP_SP_MAC((u_int16_t *)IF_LLADDR(ifp) + 1);
*sp++ = TULIP_SP_MAC((u_int16_t *)IF_LLADDR(ifp) + 2);
}
}
IF_ADDR_UNLOCK(ifp);
@ -3235,7 +3241,6 @@ tulip_reset(tulip_softc_t * const sc)
sc->tulip_flags &= ~(TULIP_DOINGSETUP|TULIP_WANTSETUP|TULIP_INRESET
|TULIP_RXACT);
tulip_addr_filter(sc);
}
@ -3259,6 +3264,7 @@ tulip_init_locked(tulip_softc_t * const sc)
CTR0(KTR_TULIP, "tulip_init_locked: up but not running, reset chip");
tulip_reset(sc);
}
tulip_addr_filter(sc);
sc->tulip_ifp->if_drv_flags |= IFF_DRV_RUNNING;
if (sc->tulip_ifp->if_flags & IFF_PROMISC) {
sc->tulip_flags |= TULIP_PROMISC;
@ -3295,6 +3301,7 @@ tulip_init_locked(tulip_softc_t * const sc)
CTR0(KTR_TULIP, "tulip_init_locked: not up, reset chip");
sc->tulip_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
tulip_reset(sc);
tulip_addr_filter(sc);
}
}
@ -4224,7 +4231,6 @@ tulip_ifioctl(struct ifnet * ifp, u_long cmd, caddr_t data)
switch (cmd) {
case SIOCSIFFLAGS: {
TULIP_LOCK(sc);
tulip_addr_filter(sc); /* reinit multicast filter */
tulip_init_locked(sc);
TULIP_UNLOCK(sc);
break;
@ -4242,26 +4248,12 @@ tulip_ifioctl(struct ifnet * ifp, u_long cmd, caddr_t data)
* Update multicast listeners
*/
TULIP_LOCK(sc);
tulip_addr_filter(sc); /* reset multicast filtering */
tulip_init_locked(sc);
TULIP_UNLOCK(sc);
error = 0;
break;
}
case SIOCSIFMTU:
/*
* Set the interface MTU.
*/
TULIP_LOCK(sc);
if (ifr->ifr_mtu > ETHERMTU) {
error = EINVAL;
break;
}
ifp->if_mtu = ifr->ifr_mtu;
TULIP_UNLOCK(sc);
break;
#ifdef SIOCGADDRROM
case SIOCGADDRROM: {
error = copyout(sc->tulip_rombuf, ifr->ifr_data, sizeof(sc->tulip_rombuf));

View File

@ -837,9 +837,9 @@ static const struct {
* endian case, just shift them left 16.
*/
#if BYTE_ORDER == BIG_ENDIAN
#define TULIP_SP_MAC(x) ((x) << 16)
#define TULIP_SP_MAC(ptr) (be16dec(ptr) << 16)
#else
#define TULIP_SP_MAC(x) (x)
#define TULIP_SP_MAC(ptr) (le16dec(ptr))
#endif
/*

View File

@ -3084,9 +3084,9 @@ tulip_addr_filter(tulip_softc_t * const sc)
hash = tulip_mchash(IF_LLADDR(ifp));
sp[hash >> 4] |= htole32(1 << (hash & 0xF));
} else {
sp[39] = TULIP_SP_MAC(((u_int16_t *)IF_LLADDR(ifp))[0]);
sp[40] = TULIP_SP_MAC(((u_int16_t *)IF_LLADDR(ifp))[1]);
sp[41] = TULIP_SP_MAC(((u_int16_t *)IF_LLADDR(ifp))[2]);
sp[39] = TULIP_SP_MAC((u_int16_t *)IF_LLADDR(ifp) + 0);
sp[40] = TULIP_SP_MAC((u_int16_t *)IF_LLADDR(ifp) + 1);
sp[41] = TULIP_SP_MAC((u_int16_t *)IF_LLADDR(ifp) + 2);
}
}
}
@ -3101,26 +3101,32 @@ tulip_addr_filter(tulip_softc_t * const sc)
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
addrp = LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
*sp++ = TULIP_SP_MAC(((u_int16_t *)addrp)[0]);
*sp++ = TULIP_SP_MAC(((u_int16_t *)addrp)[1]);
*sp++ = TULIP_SP_MAC(((u_int16_t *)addrp)[2]);
*sp++ = TULIP_SP_MAC((u_int16_t *)addrp + 0);
*sp++ = TULIP_SP_MAC((u_int16_t *)addrp + 1);
*sp++ = TULIP_SP_MAC((u_int16_t *)addrp + 2);
idx++;
}
/*
* Add the broadcast address.
*/
idx++;
*sp++ = TULIP_SP_MAC(0xFFFF);
*sp++ = TULIP_SP_MAC(0xFFFF);
*sp++ = TULIP_SP_MAC(0xFFFF);
#if BYTE_ORDER == BIG_ENDIAN
*sp++ = 0xFFFF << 16;
*sp++ = 0xFFFF << 16;
*sp++ = 0xFFFF << 16;
#else
*sp++ = 0xFFFF;
*sp++ = 0xFFFF;
*sp++ = 0xFFFF;
#endif
}
/*
* Pad the rest with our hardware address
*/
for (; idx < 16; idx++) {
*sp++ = TULIP_SP_MAC(((u_int16_t *)IF_LLADDR(ifp))[0]);
*sp++ = TULIP_SP_MAC(((u_int16_t *)IF_LLADDR(ifp))[1]);
*sp++ = TULIP_SP_MAC(((u_int16_t *)IF_LLADDR(ifp))[2]);
*sp++ = TULIP_SP_MAC((u_int16_t *)IF_LLADDR(ifp) + 0);
*sp++ = TULIP_SP_MAC((u_int16_t *)IF_LLADDR(ifp) + 1);
*sp++ = TULIP_SP_MAC((u_int16_t *)IF_LLADDR(ifp) + 2);
}
}
IF_ADDR_UNLOCK(ifp);
@ -3235,7 +3241,6 @@ tulip_reset(tulip_softc_t * const sc)
sc->tulip_flags &= ~(TULIP_DOINGSETUP|TULIP_WANTSETUP|TULIP_INRESET
|TULIP_RXACT);
tulip_addr_filter(sc);
}
@ -3259,6 +3264,7 @@ tulip_init_locked(tulip_softc_t * const sc)
CTR0(KTR_TULIP, "tulip_init_locked: up but not running, reset chip");
tulip_reset(sc);
}
tulip_addr_filter(sc);
sc->tulip_ifp->if_drv_flags |= IFF_DRV_RUNNING;
if (sc->tulip_ifp->if_flags & IFF_PROMISC) {
sc->tulip_flags |= TULIP_PROMISC;
@ -3295,6 +3301,7 @@ tulip_init_locked(tulip_softc_t * const sc)
CTR0(KTR_TULIP, "tulip_init_locked: not up, reset chip");
sc->tulip_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
tulip_reset(sc);
tulip_addr_filter(sc);
}
}
@ -4224,7 +4231,6 @@ tulip_ifioctl(struct ifnet * ifp, u_long cmd, caddr_t data)
switch (cmd) {
case SIOCSIFFLAGS: {
TULIP_LOCK(sc);
tulip_addr_filter(sc); /* reinit multicast filter */
tulip_init_locked(sc);
TULIP_UNLOCK(sc);
break;
@ -4242,26 +4248,12 @@ tulip_ifioctl(struct ifnet * ifp, u_long cmd, caddr_t data)
* Update multicast listeners
*/
TULIP_LOCK(sc);
tulip_addr_filter(sc); /* reset multicast filtering */
tulip_init_locked(sc);
TULIP_UNLOCK(sc);
error = 0;
break;
}
case SIOCSIFMTU:
/*
* Set the interface MTU.
*/
TULIP_LOCK(sc);
if (ifr->ifr_mtu > ETHERMTU) {
error = EINVAL;
break;
}
ifp->if_mtu = ifr->ifr_mtu;
TULIP_UNLOCK(sc);
break;
#ifdef SIOCGADDRROM
case SIOCGADDRROM: {
error = copyout(sc->tulip_rombuf, ifr->ifr_data, sizeof(sc->tulip_rombuf));

View File

@ -837,9 +837,9 @@ static const struct {
* endian case, just shift them left 16.
*/
#if BYTE_ORDER == BIG_ENDIAN
#define TULIP_SP_MAC(x) ((x) << 16)
#define TULIP_SP_MAC(ptr) (be16dec(ptr) << 16)
#else
#define TULIP_SP_MAC(x) (x)
#define TULIP_SP_MAC(ptr) (le16dec(ptr))
#endif
/*