summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2005-02-08 11:08:57 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2005-02-08 11:08:57 +0000
commitb446f1a72b19951eed072490294f1706b8d57e66 (patch)
tree7e515a08b4cd03ac6daa401b0497d7db55863ac7 /sys/dev
parent2db005f5137ee07899a84b7817531729c145d056 (diff)
From NetBSD:
sys/dev/ic/rtw.c rev 1.38: Use clue from rtk(4) and re(4) to fix the rtw(4) packet filter. Previously, I was using the wrong CRC32 function to hash multicast addresses; to compensate, I set the multicast filter to all 1s. Now that I hash the addresses correctly, I do not any longer set the filter to all 1s. In rtw_ioctl, avoid gratuitous re-initialization when the interface flags change. If a !IFF_UP -> IFF_UP transition, call rtw_init(); otherwise, only reload the packet filter. sys/dev/ic/rtwreg.h rev 1.10: Put useful combinations of Receiver Control Register flags in RTW_RCR_PKTFILT_MASK, RTW_RCR_MONITOR, and RTW_RCR_PKTFILT_DEFAULT. (XXX RTW_RCR_MONITOR should be called RTW_RCR_PKTFILT_MONITOR.)
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/rtw.c92
-rw-r--r--sys/dev/ic/rtwreg.h33
2 files changed, 73 insertions, 52 deletions
diff --git a/sys/dev/ic/rtw.c b/sys/dev/ic/rtw.c
index 2c523563768..6ff6745afa2 100644
--- a/sys/dev/ic/rtw.c
+++ b/sys/dev/ic/rtw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtw.c,v 1.14 2005/02/06 21:57:06 pedro Exp $ */
+/* $OpenBSD: rtw.c,v 1.15 2005/02/08 11:08:56 jsg Exp $ */
/* $NetBSD: rtw.c,v 1.29 2004/12/27 19:49:16 dyoung Exp $ */
/*-
* Copyright (c) 2004, 2005 David Young. All rights reserved.
@@ -2212,9 +2212,8 @@ rtw_set_nettype(struct rtw_softc *sc, enum ieee80211_opmode opmode)
rtw_set_access(&sc->sc_regs, RTW_ACCESS_NONE);
}
-/* XXX is the endianness correct? test. */
#define rtw_calchash(addr) \
- (ether_crc32_le((addr), IEEE80211_ADDR_LEN) & BITS(5, 0))
+ (ether_crc32_be((addr), IEEE80211_ADDR_LEN) >> 26)
void
rtw_pktfilt_load(struct rtw_softc *sc)
@@ -2230,31 +2229,34 @@ rtw_pktfilt_load(struct rtw_softc *sc)
/* XXX might be necessary to stop Rx/Tx engines while setting filters */
-#define RTW_RCR_MONITOR (RTW_RCR_ACRC32|RTW_RCR_APM|RTW_RCR_AAP|RTW_RCR_AB|RTW_RCR_ACF | RTW_RCR_AICV | RTW_RCR_ACRC32)
+ sc->sc_rcr &= ~RTW_RCR_PKTFILTER_MASK;
+ sc->sc_rcr &= ~(RTW_RCR_MXDMA_MASK | RTW_RCR_RXFTH_MASK);
- if (ic->ic_opmode == IEEE80211_M_MONITOR)
- sc->sc_rcr |= RTW_RCR_MONITOR;
- else
- sc->sc_rcr &= ~RTW_RCR_MONITOR;
-
- /* XXX reference sources BEGIN */
+ sc->sc_rcr |= RTW_RCR_PKTFILTER_DEFAULT;
+ /* MAC auto-reset PHY (huh?) */
sc->sc_rcr |= RTW_RCR_ENMARP;
- sc->sc_rcr |= RTW_RCR_AB | RTW_RCR_AM | RTW_RCR_APM;
-#if 0
- /* receive broadcasts in our BSS */
- sc->sc_rcr |= RTW_RCR_ADD3;
-#endif
- /* XXX reference sources END */
+ /* DMA whole Rx packets, only. Set Tx DMA burst size to 1024 bytes. */
+ sc->sc_rcr |= RTW_RCR_MXDMA_1024 | RTW_RCR_RXFTH_WHOLE;
- /* receive pwrmgmt frames. */
- sc->sc_rcr |= RTW_RCR_APWRMGT;
- /* receive mgmt/ctrl/data frames. */
- sc->sc_rcr |= RTW_RCR_ADF | RTW_RCR_AMF;
- /* initialize Rx DMA threshold, Tx DMA burst size */
- sc->sc_rcr |= RTW_RCR_RXFTH_WHOLE | RTW_RCR_MXDMA_1024;
+ switch (ic->ic_opmode) {
+ case IEEE80211_M_MONITOR:
+ sc->sc_rcr |= RTW_RCR_MONITOR;
+ break;
+ case IEEE80211_M_AHDEMO:
+ case IEEE80211_M_IBSS:
+ /* receive broadcasts in our BSS */
+ sc->sc_rcr |= RTW_RCR_ADD3;
+ break;
+ default:
+ break;
+ }
ifp->if_flags &= ~IFF_ALLMULTI;
+ /* XXX accept all broadcast if scanning */
+ if ((ifp->if_flags & IFF_BROADCAST) != 0)
+ sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */
+
if (ifp->if_flags & IFF_PROMISC) {
sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */
allmulti:
@@ -2273,27 +2275,20 @@ allmulti:
goto allmulti;
hash = rtw_calchash(enm->enm_addrlo);
- hashes[hash >> 5] |= 1 << (hash & 0x1f);
+ hashes[hash >> 5] |= (1 << (hash & 0x1f));
+ sc->sc_rcr |= RTW_RCR_AM;
ETHER_NEXT_MULTI(step, enm);
}
- if (ifp->if_flags & IFF_BROADCAST) {
- hash = rtw_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)
+ if (ifp->if_flags & IFF_ALLMULTI) {
sc->sc_rcr |= RTW_RCR_AM; /* accept all multicast */
-
- if (ic->ic_state == IEEE80211_S_SCAN)
- sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */
-
- hashes[0] = hashes[1] = 0xffffffff;
+ hashes[0] = hashes[1] = 0xffffffff;
+ }
RTW_WRITE(regs, RTW_MAR0, hashes[0]);
RTW_WRITE(regs, RTW_MAR1, hashes[1]);
@@ -2415,7 +2410,7 @@ rtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCSIFFLAGS:
if ((ifp->if_flags & IFF_UP) != 0) {
- if (0 && (sc->sc_flags & RTW_F_ENABLED) != 0) {
+ if ((sc->sc_flags & RTW_F_ENABLED) != 0) {
rtw_pktfilt_load(sc);
} else
rc = rtw_init(ifp);
@@ -2947,24 +2942,19 @@ rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
break;
case IEEE80211_S_RUN:
- if (ic->ic_opmode == IEEE80211_M_STA)
+ switch (ic->ic_opmode) {
+ case IEEE80211_M_AHDEMO:
+ case IEEE80211_M_HOSTAP:
+ case IEEE80211_M_IBSS:
+ rtw_join_bss(sc, ic->ic_bss->ni_bssid, ic->ic_opmode,
+ ic->ic_bss->ni_intval);
break;
- /*FALLTHROUGH*/
- case IEEE80211_S_AUTH:
-#if 0
- rtw_write_bcn_thresh(sc);
- rtw_write_ssid(sc);
- rtw_write_sup_rates(sc);
-#endif
- if (ic->ic_opmode == IEEE80211_M_AHDEMO ||
- ic->ic_opmode == IEEE80211_M_MONITOR)
+ case IEEE80211_M_MONITOR:
+ case IEEE80211_M_STA:
break;
-
- /* TBD set listen interval */
-
-#if 0
- rtw_tsf(sc);
-#endif
+ }
+ break;
+ case IEEE80211_S_AUTH:
break;
}
diff --git a/sys/dev/ic/rtwreg.h b/sys/dev/ic/rtwreg.h
index 6d4ae58c6a6..de84461801c 100644
--- a/sys/dev/ic/rtwreg.h
+++ b/sys/dev/ic/rtwreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtwreg.h,v 1.3 2005/01/22 10:14:25 jsg Exp $ */
+/* $OpenBSD: rtwreg.h,v 1.4 2005/02/08 11:08:56 jsg Exp $ */
/* $NetBSD: rtwreg.h,v 1.4 2004/12/21 09:07:23 dyoung Exp $ */
/*-
* Copyright (c) 2004, 2005 David Young. All rights reserved.
@@ -305,6 +305,37 @@
#define RTW_RCR_APM BIT(1)
#define RTW_RCR_AAP BIT(0) /* accept frames w/ destination */
+/* Additional bits to set in monitor mode. */
+#define RTW_RCR_MONITOR ( \
+ RTW_RCR_AAP | \
+ RTW_RCR_ACF | \
+ RTW_RCR_ACRC32 | \
+ RTW_RCR_AICV | \
+ 0)
+
+/* The packet filter bits. */
+#define RTW_RCR_PKTFILTER_MASK (\
+ RTW_RCR_AAP | \
+ RTW_RCR_AB | \
+ RTW_RCR_ACF | \
+ RTW_RCR_ACRC32 | \
+ RTW_RCR_ADD3 | \
+ RTW_RCR_ADF | \
+ RTW_RCR_AICV | \
+ RTW_RCR_AM | \
+ RTW_RCR_AMF | \
+ RTW_RCR_APM | \
+ RTW_RCR_APWRMGT | \
+ 0)
+
+/* Receive power-management frames and mgmt/ctrl/data frames. */
+#define RTW_RCR_PKTFILTER_DEFAULT ( \
+ RTW_RCR_ADF | \
+ RTW_RCR_AMF | \
+ RTW_RCR_APM | \
+ RTW_RCR_APWRMGT | \
+ 0)
+
#define RTW_TINT 0x48 /* Timer Interrupt Register, 32b */
#define RTW_TBDA 0x4c /* Transmit Beacon Descriptor Start Address,
* 32b, 256-byte alignment