diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2005-02-08 11:08:57 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2005-02-08 11:08:57 +0000 |
commit | b446f1a72b19951eed072490294f1706b8d57e66 (patch) | |
tree | 7e515a08b4cd03ac6daa401b0497d7db55863ac7 | |
parent | 2db005f5137ee07899a84b7817531729c145d056 (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.)
-rw-r--r-- | sys/dev/ic/rtw.c | 92 | ||||
-rw-r--r-- | sys/dev/ic/rtwreg.h | 33 |
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 |