summaryrefslogtreecommitdiff
path: root/sys/dev/ic/atw.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2004-07-15 15:11:03 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2004-07-15 15:11:03 +0000
commit6ac578cbde8a913dbd15b971bd791c2bd0cc85c6 (patch)
treebc62b13de907220de814df300c228a9029b43bbc /sys/dev/ic/atw.c
parent784d42662f31f3db6f6a7259e300a1ec8205ca63 (diff)
missing bits from last commit
Diffstat (limited to 'sys/dev/ic/atw.c')
-rw-r--r--sys/dev/ic/atw.c82
1 files changed, 41 insertions, 41 deletions
diff --git a/sys/dev/ic/atw.c b/sys/dev/ic/atw.c
index 447cd220891..9255d314b02 100644
--- a/sys/dev/ic/atw.c
+++ b/sys/dev/ic/atw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: atw.c,v 1.14 2004/07/15 13:00:49 millert Exp $ */
+/* $OpenBSD: atw.c,v 1.15 2004/07/15 15:11:02 millert Exp $ */
/* $NetBSD: atw.c,v 1.57 2004/07/15 07:11:23 dyoung Exp $ */
/*-
@@ -1615,19 +1615,33 @@ atw_rf3000_write(struct atw_softc *sc, u_int addr, u_int val)
u_int32_t reg;
int i;
+ for (i = 1000; --i >= 0; ) {
+ if (ATW_ISSET(sc, ATW_BBPCTL, ATW_BBPCTL_RD|ATW_BBPCTL_WR) == 0)
+ break;
+ DELAY(100);
+ }
+
+ if (i < 0) {
+ printf("%s: BBPCTL busy (pre-write)\n", sc->sc_dev.dv_xname);
+ return ETIMEDOUT;
+ }
+
reg = sc->sc_bbpctl_wr |
LSHIFT(val & 0xff, ATW_BBPCTL_DATA_MASK) |
LSHIFT(addr & 0x7f, ATW_BBPCTL_ADDR_MASK);
- for (i = 10; --i >= 0; ) {
- ATW_WRITE(sc, ATW_BBPCTL, reg);
- DELAY(2000);
+ ATW_WRITE(sc, ATW_BBPCTL, reg);
+
+ for (i = 1000; --i >= 0; ) {
+ DELAY(100);
if (ATW_ISSET(sc, ATW_BBPCTL, ATW_BBPCTL_WR) == 0)
break;
}
+ ATW_CLR(sc, ATW_BBPCTL, ATW_BBPCTL_WR);
+
if (i < 0) {
- printf("%s: BBPCTL still busy\n", sc->sc_dev.dv_xname);
+ printf("%s: BBPCTL busy (post-write)\n", sc->sc_dev.dv_xname);
return ETIMEDOUT;
}
return 0;
@@ -1811,38 +1825,36 @@ atw_filter_setup(struct atw_softc *sc)
#endif
struct ifnet *ifp = &sc->sc_ic.ic_if;
int hash;
- u_int32_t hashes[2] = { 0, 0 };
+ u_int32_t hashes[2];
struct ether_multi *enm;
struct ether_multistep step;
- DPRINTF(sc, ("%s: atw_filter_setup: sc_flags 0x%08x\n",
- sc->sc_dev.dv_xname, sc->sc_flags));
-
- /*
- * If we're running, idle the receive engine. If we're NOT running,
- * we're being called from atw_init(), and our writing ATW_NAR will
- * start the transmit and receive processes in motion.
+ /* According to comments in tlp_al981_filter_setup
+ * (dev/ic/tulip.c) the ADMtek AL981 does not like for its
+ * multicast filter to be set while it is running. Hopefully
+ * the ADM8211 is not the same!
*/
- if (ifp->if_flags & IFF_RUNNING)
+ if ((ifp->if_flags & IFF_RUNNING) != 0)
atw_idle(sc, ATW_NAR_SR);
sc->sc_opmode &= ~(ATW_NAR_PR|ATW_NAR_MM);
- ifp->if_flags &= ~IFF_ALLMULTI;
-
- if (ifp->if_flags & IFF_PROMISC) {
+ /* XXX in scan mode, do not filter packets. Maybe this is
+ * unnecessary.
+ */
+ if (ic->ic_state == IEEE80211_S_SCAN ||
+ (ifp->if_flags & IFF_PROMISC) != 0) {
sc->sc_opmode |= ATW_NAR_PR;
-allmulti:
- ifp->if_flags |= IFF_ALLMULTI;
- goto setit;
+ goto allmulti;
}
+ hashes[0] = hashes[1] = 0x0;
+
/*
* Program the 64-bit multicast hash filter.
*/
ETHER_FIRST_MULTI(step, ec, enm);
while (enm != NULL) {
- /* XXX */
if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
ETHER_ADDR_LEN) != 0)
goto allmulti;
@@ -1851,33 +1863,21 @@ allmulti:
hashes[hash >> 5] |= 1 << (hash & 0x1f);
ETHER_NEXT_MULTI(step, enm);
}
+ ifp->if_flags &= ~IFF_ALLMULTI;
+ goto setit;
- if (ifp->if_flags & IFF_BROADCAST) {
- hash = atw_calchash(etherbroadcastaddr);
- hashes[hash >> 5] |= 1 << (hash & 0x1f);
- }
-
- /* all bits set => hash is useless */
- if (~(hashes[0] & hashes[1]) == 0)
- goto allmulti;
-
- setit:
- if (ifp->if_flags & IFF_ALLMULTI)
- sc->sc_opmode |= ATW_NAR_MM;
-
- /* XXX in scan mode, do not filter packets. maybe this is
- * unnecessary.
- */
- if (ic->ic_state == IEEE80211_S_SCAN)
- sc->sc_opmode |= ATW_NAR_PR;
+allmulti:
+ ifp->if_flags |= IFF_ALLMULTI;
+ hashes[0] = hashes[1] = 0xffffffff;
+setit:
ATW_WRITE(sc, ATW_MAR0, hashes[0]);
ATW_WRITE(sc, ATW_MAR1, hashes[1]);
ATW_WRITE(sc, ATW_NAR, sc->sc_opmode);
+ DELAY(20 * 1000);
+
DPRINTF(sc, ("%s: ATW_NAR %08x opmode %08x\n", sc->sc_dev.dv_xname,
ATW_READ(sc, ATW_NAR), sc->sc_opmode));
-
- DPRINTF(sc, ("%s: atw_filter_setup: returning\n", sc->sc_dev.dv_xname));
}
/* Tell the ADM8211 our preferred BSSID. The ADM8211 must match