1 1.137 msaitoh /* $NetBSD: rtw.c,v 1.137 2021/11/10 16:17:34 msaitoh Exp $ */ 2 1.1 dyoung /*- 3 1.93 dyoung * Copyright (c) 2004, 2005, 2006, 2007 David Young. All rights 4 1.93 dyoung * reserved. 5 1.1 dyoung * 6 1.1 dyoung * Programmed for NetBSD by David Young. 7 1.1 dyoung * 8 1.1 dyoung * Redistribution and use in source and binary forms, with or without 9 1.1 dyoung * modification, are permitted provided that the following conditions 10 1.1 dyoung * are met: 11 1.1 dyoung * 1. Redistributions of source code must retain the above copyright 12 1.1 dyoung * notice, this list of conditions and the following disclaimer. 13 1.1 dyoung * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 dyoung * notice, this list of conditions and the following disclaimer in the 15 1.1 dyoung * documentation and/or other materials provided with the distribution. 16 1.1 dyoung * 17 1.1 dyoung * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY 18 1.1 dyoung * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 19 1.1 dyoung * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 20 1.1 dyoung * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David 21 1.1 dyoung * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 1.1 dyoung * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 23 1.1 dyoung * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 1.1 dyoung * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 1.1 dyoung * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 1.1 dyoung * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 1.1 dyoung * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 28 1.1 dyoung * OF SUCH DAMAGE. 29 1.1 dyoung */ 30 1.1 dyoung /* 31 1.1 dyoung * Device driver for the Realtek RTL8180 802.11 MAC/BBP. 32 1.1 dyoung */ 33 1.1 dyoung 34 1.1 dyoung #include <sys/cdefs.h> 35 1.137 msaitoh __KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.137 2021/11/10 16:17:34 msaitoh Exp $"); 36 1.1 dyoung 37 1.1 dyoung 38 1.1 dyoung #include <sys/param.h> 39 1.4 dyoung #include <sys/sysctl.h> 40 1.44 perry #include <sys/systm.h> 41 1.1 dyoung #include <sys/callout.h> 42 1.44 perry #include <sys/mbuf.h> 43 1.1 dyoung #include <sys/malloc.h> 44 1.1 dyoung #include <sys/kernel.h> 45 1.1 dyoung #include <sys/time.h> 46 1.1 dyoung #include <sys/types.h> 47 1.99 tsutsui #include <sys/device.h> 48 1.118 uebayasi #include <sys/sockio.h> 49 1.1 dyoung 50 1.1 dyoung #include <machine/endian.h> 51 1.91 ad #include <sys/bus.h> 52 1.91 ad #include <sys/intr.h> /* splnet */ 53 1.1 dyoung 54 1.1 dyoung #include <net/if.h> 55 1.1 dyoung #include <net/if_media.h> 56 1.1 dyoung #include <net/if_ether.h> 57 1.1 dyoung 58 1.48 dyoung #include <net80211/ieee80211_netbsd.h> 59 1.1 dyoung #include <net80211/ieee80211_var.h> 60 1.1 dyoung #include <net80211/ieee80211_radiotap.h> 61 1.1 dyoung 62 1.1 dyoung #include <net/bpf.h> 63 1.1 dyoung 64 1.1 dyoung #include <dev/ic/rtwreg.h> 65 1.1 dyoung #include <dev/ic/rtwvar.h> 66 1.1 dyoung #include <dev/ic/rtwphyio.h> 67 1.1 dyoung #include <dev/ic/rtwphy.h> 68 1.1 dyoung 69 1.1 dyoung #include <dev/ic/smc93cx6var.h> 70 1.1 dyoung 71 1.58 dyoung static int rtw_rfprog_fallback = 0; 72 1.58 dyoung static int rtw_host_rfio = 0; 73 1.4 dyoung 74 1.1 dyoung #ifdef RTW_DEBUG 75 1.21 dyoung int rtw_debug = 0; 76 1.58 dyoung static int rtw_rxbufs_limit = RTW_RXQLEN; 77 1.1 dyoung #endif /* RTW_DEBUG */ 78 1.1 dyoung 79 1.21 dyoung #define NEXT_ATTACH_STATE(sc, state) do { \ 80 1.21 dyoung DPRINTF(sc, RTW_DEBUG_ATTACH, \ 81 1.21 dyoung ("%s: attach state %s\n", __func__, #state)); \ 82 1.21 dyoung sc->sc_attach_state = state; \ 83 1.1 dyoung } while (0) 84 1.1 dyoung 85 1.26 dyoung int rtw_dwelltime = 200; /* milliseconds */ 86 1.50 dyoung static struct ieee80211_cipher rtw_cipher_wep; 87 1.1 dyoung 88 1.101 dyoung static void rtw_disable_interrupts(struct rtw_regs *); 89 1.101 dyoung static void rtw_enable_interrupts(struct rtw_softc *); 90 1.101 dyoung 91 1.101 dyoung static int rtw_init(struct ifnet *); 92 1.125 nonaka static void rtw_softintr(void *); 93 1.101 dyoung 94 1.5 dyoung static void rtw_start(struct ifnet *); 95 1.58 dyoung static void rtw_reset_oactive(struct rtw_softc *); 96 1.58 dyoung static struct mbuf *rtw_beacon_alloc(struct rtw_softc *, 97 1.58 dyoung struct ieee80211_node *); 98 1.58 dyoung static u_int rtw_txring_next(struct rtw_regs *, struct rtw_txdesc_blk *); 99 1.5 dyoung 100 1.83 dyoung static void rtw_io_enable(struct rtw_softc *, uint8_t, int); 101 1.49 dyoung static int rtw_key_delete(struct ieee80211com *, const struct ieee80211_key *); 102 1.49 dyoung static int rtw_key_set(struct ieee80211com *, const struct ieee80211_key *, 103 1.131 msaitoh const uint8_t[IEEE80211_ADDR_LEN]); 104 1.49 dyoung static void rtw_key_update_end(struct ieee80211com *); 105 1.49 dyoung static void rtw_key_update_begin(struct ieee80211com *); 106 1.54 dogcow static int rtw_wep_decap(struct ieee80211_key *, struct mbuf *, int); 107 1.49 dyoung static void rtw_wep_setkeys(struct rtw_softc *, struct ieee80211_key *, int); 108 1.49 dyoung 109 1.45 dyoung static void rtw_led_attach(struct rtw_led_state *, void *); 110 1.101 dyoung static void rtw_led_detach(struct rtw_led_state *); 111 1.42 dyoung static void rtw_led_init(struct rtw_regs *); 112 1.42 dyoung static void rtw_led_slowblink(void *); 113 1.42 dyoung static void rtw_led_fastblink(void *); 114 1.42 dyoung static void rtw_led_set(struct rtw_led_state *, struct rtw_regs *, int); 115 1.42 dyoung 116 1.4 dyoung static int rtw_sysctl_verify_rfio(SYSCTLFN_PROTO); 117 1.4 dyoung static int rtw_sysctl_verify_rfprog(SYSCTLFN_PROTO); 118 1.4 dyoung #ifdef RTW_DEBUG 119 1.83 dyoung static void rtw_dump_rings(struct rtw_softc *sc); 120 1.21 dyoung static void rtw_print_txdesc(struct rtw_softc *, const char *, 121 1.34 dyoung struct rtw_txsoft *, struct rtw_txdesc_blk *, int); 122 1.4 dyoung static int rtw_sysctl_verify_debug(SYSCTLFN_PROTO); 123 1.31 dyoung static int rtw_sysctl_verify_rxbufs_limit(SYSCTLFN_PROTO); 124 1.4 dyoung #endif /* RTW_DEBUG */ 125 1.83 dyoung #ifdef RTW_DIAG 126 1.83 dyoung static void rtw_txring_fixup(struct rtw_softc *sc, const char *fn, int ln); 127 1.83 dyoung #endif /* RTW_DIAG */ 128 1.4 dyoung 129 1.4 dyoung /* 130 1.4 dyoung * Setup sysctl(3) MIB, hw.rtw.* 131 1.4 dyoung * 132 1.106 ad * TBD condition CTLFLAG_PERMANENT on being a module or not 133 1.4 dyoung */ 134 1.4 dyoung SYSCTL_SETUP(sysctl_rtw, "sysctl rtw(4) subtree setup") 135 1.4 dyoung { 136 1.4 dyoung int rc; 137 1.47 atatat const struct sysctlnode *cnode, *rnode; 138 1.4 dyoung 139 1.4 dyoung if ((rc = sysctl_createv(clog, 0, NULL, &rnode, 140 1.4 dyoung CTLFLAG_PERMANENT, CTLTYPE_NODE, "rtw", 141 1.4 dyoung "Realtek RTL818x 802.11 controls", 142 1.121 pooka NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) 143 1.4 dyoung goto err; 144 1.4 dyoung 145 1.4 dyoung #ifdef RTW_DEBUG 146 1.4 dyoung /* control debugging printfs */ 147 1.4 dyoung if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 148 1.131 msaitoh CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 149 1.4 dyoung "debug", SYSCTL_DESCR("Enable RTL818x debugging output"), 150 1.4 dyoung rtw_sysctl_verify_debug, 0, &rtw_debug, 0, 151 1.4 dyoung CTL_CREATE, CTL_EOL)) != 0) 152 1.4 dyoung goto err; 153 1.31 dyoung 154 1.31 dyoung /* Limit rx buffers, for simulating resource exhaustion. */ 155 1.31 dyoung if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 156 1.131 msaitoh CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 157 1.31 dyoung "rxbufs_limit", 158 1.31 dyoung SYSCTL_DESCR("Set rx buffers limit"), 159 1.31 dyoung rtw_sysctl_verify_rxbufs_limit, 0, &rtw_rxbufs_limit, 0, 160 1.31 dyoung CTL_CREATE, CTL_EOL)) != 0) 161 1.31 dyoung goto err; 162 1.31 dyoung 163 1.4 dyoung #endif /* RTW_DEBUG */ 164 1.4 dyoung /* set fallback RF programming method */ 165 1.4 dyoung if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 166 1.131 msaitoh CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 167 1.4 dyoung "rfprog_fallback", 168 1.4 dyoung SYSCTL_DESCR("Set fallback RF programming method"), 169 1.4 dyoung rtw_sysctl_verify_rfprog, 0, &rtw_rfprog_fallback, 0, 170 1.4 dyoung CTL_CREATE, CTL_EOL)) != 0) 171 1.4 dyoung goto err; 172 1.4 dyoung 173 1.4 dyoung /* force host to control RF I/O bus */ 174 1.4 dyoung if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 175 1.131 msaitoh CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 176 1.4 dyoung "host_rfio", SYSCTL_DESCR("Enable host control of RF I/O"), 177 1.4 dyoung rtw_sysctl_verify_rfio, 0, &rtw_host_rfio, 0, 178 1.4 dyoung CTL_CREATE, CTL_EOL)) != 0) 179 1.4 dyoung goto err; 180 1.4 dyoung 181 1.4 dyoung return; 182 1.4 dyoung err: 183 1.4 dyoung printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); 184 1.4 dyoung } 185 1.4 dyoung 186 1.4 dyoung static int 187 1.4 dyoung rtw_sysctl_verify(SYSCTLFN_ARGS, int lower, int upper) 188 1.4 dyoung { 189 1.4 dyoung int error, t; 190 1.4 dyoung struct sysctlnode node; 191 1.4 dyoung 192 1.4 dyoung node = *rnode; 193 1.4 dyoung t = *(int*)rnode->sysctl_data; 194 1.4 dyoung node.sysctl_data = &t; 195 1.4 dyoung error = sysctl_lookup(SYSCTLFN_CALL(&node)); 196 1.4 dyoung if (error || newp == NULL) 197 1.4 dyoung return (error); 198 1.4 dyoung 199 1.4 dyoung if (t < lower || t > upper) 200 1.4 dyoung return (EINVAL); 201 1.4 dyoung 202 1.4 dyoung *(int*)rnode->sysctl_data = t; 203 1.4 dyoung 204 1.4 dyoung return (0); 205 1.4 dyoung } 206 1.4 dyoung 207 1.4 dyoung static int 208 1.4 dyoung rtw_sysctl_verify_rfprog(SYSCTLFN_ARGS) 209 1.4 dyoung { 210 1.46 dyoung return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)), 0, 211 1.75 dyoung __SHIFTOUT(RTW_CONFIG4_RFTYPE_MASK, RTW_CONFIG4_RFTYPE_MASK)); 212 1.4 dyoung } 213 1.4 dyoung 214 1.4 dyoung static int 215 1.4 dyoung rtw_sysctl_verify_rfio(SYSCTLFN_ARGS) 216 1.4 dyoung { 217 1.46 dyoung return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)), 0, 1); 218 1.4 dyoung } 219 1.4 dyoung 220 1.1 dyoung #ifdef RTW_DEBUG 221 1.4 dyoung static int 222 1.4 dyoung rtw_sysctl_verify_debug(SYSCTLFN_ARGS) 223 1.4 dyoung { 224 1.46 dyoung return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)), 225 1.46 dyoung 0, RTW_DEBUG_MAX); 226 1.4 dyoung } 227 1.4 dyoung 228 1.31 dyoung static int 229 1.31 dyoung rtw_sysctl_verify_rxbufs_limit(SYSCTLFN_ARGS) 230 1.31 dyoung { 231 1.46 dyoung return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)), 232 1.46 dyoung 0, RTW_RXQLEN); 233 1.31 dyoung } 234 1.31 dyoung 235 1.1 dyoung static void 236 1.1 dyoung rtw_print_regs(struct rtw_regs *regs, const char *dvname, const char *where) 237 1.1 dyoung { 238 1.21 dyoung #define PRINTREG32(sc, reg) \ 239 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 240 1.21 dyoung ("%s: reg[ " #reg " / %03x ] = %08x\n", \ 241 1.1 dyoung dvname, reg, RTW_READ(regs, reg))) 242 1.1 dyoung 243 1.21 dyoung #define PRINTREG16(sc, reg) \ 244 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 245 1.21 dyoung ("%s: reg[ " #reg " / %03x ] = %04x\n", \ 246 1.1 dyoung dvname, reg, RTW_READ16(regs, reg))) 247 1.1 dyoung 248 1.21 dyoung #define PRINTREG8(sc, reg) \ 249 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 250 1.21 dyoung ("%s: reg[ " #reg " / %03x ] = %02x\n", \ 251 1.1 dyoung dvname, reg, RTW_READ8(regs, reg))) 252 1.1 dyoung 253 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_REGDUMP, ("%s: %s\n", dvname, where)); 254 1.1 dyoung 255 1.1 dyoung PRINTREG32(regs, RTW_IDR0); 256 1.1 dyoung PRINTREG32(regs, RTW_IDR1); 257 1.1 dyoung PRINTREG32(regs, RTW_MAR0); 258 1.1 dyoung PRINTREG32(regs, RTW_MAR1); 259 1.1 dyoung PRINTREG32(regs, RTW_TSFTRL); 260 1.1 dyoung PRINTREG32(regs, RTW_TSFTRH); 261 1.1 dyoung PRINTREG32(regs, RTW_TLPDA); 262 1.1 dyoung PRINTREG32(regs, RTW_TNPDA); 263 1.1 dyoung PRINTREG32(regs, RTW_THPDA); 264 1.1 dyoung PRINTREG32(regs, RTW_TCR); 265 1.1 dyoung PRINTREG32(regs, RTW_RCR); 266 1.1 dyoung PRINTREG32(regs, RTW_TINT); 267 1.1 dyoung PRINTREG32(regs, RTW_TBDA); 268 1.1 dyoung PRINTREG32(regs, RTW_ANAPARM); 269 1.1 dyoung PRINTREG32(regs, RTW_BB); 270 1.1 dyoung PRINTREG32(regs, RTW_PHYCFG); 271 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP0L); 272 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP0H); 273 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP1L); 274 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP1H); 275 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP2LL); 276 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP2LH); 277 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP2HL); 278 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP2HH); 279 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP3LL); 280 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP3LH); 281 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP3HL); 282 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP3HH); 283 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP4LL); 284 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP4LH); 285 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP4HL); 286 1.1 dyoung PRINTREG32(regs, RTW_WAKEUP4HH); 287 1.1 dyoung PRINTREG32(regs, RTW_DK0); 288 1.1 dyoung PRINTREG32(regs, RTW_DK1); 289 1.1 dyoung PRINTREG32(regs, RTW_DK2); 290 1.1 dyoung PRINTREG32(regs, RTW_DK3); 291 1.1 dyoung PRINTREG32(regs, RTW_RETRYCTR); 292 1.1 dyoung PRINTREG32(regs, RTW_RDSAR); 293 1.1 dyoung PRINTREG32(regs, RTW_FER); 294 1.1 dyoung PRINTREG32(regs, RTW_FEMR); 295 1.1 dyoung PRINTREG32(regs, RTW_FPSR); 296 1.1 dyoung PRINTREG32(regs, RTW_FFER); 297 1.1 dyoung 298 1.1 dyoung /* 16-bit registers */ 299 1.1 dyoung PRINTREG16(regs, RTW_BRSR); 300 1.1 dyoung PRINTREG16(regs, RTW_IMR); 301 1.1 dyoung PRINTREG16(regs, RTW_ISR); 302 1.1 dyoung PRINTREG16(regs, RTW_BCNITV); 303 1.1 dyoung PRINTREG16(regs, RTW_ATIMWND); 304 1.1 dyoung PRINTREG16(regs, RTW_BINTRITV); 305 1.1 dyoung PRINTREG16(regs, RTW_ATIMTRITV); 306 1.1 dyoung PRINTREG16(regs, RTW_CRC16ERR); 307 1.1 dyoung PRINTREG16(regs, RTW_CRC0); 308 1.1 dyoung PRINTREG16(regs, RTW_CRC1); 309 1.1 dyoung PRINTREG16(regs, RTW_CRC2); 310 1.1 dyoung PRINTREG16(regs, RTW_CRC3); 311 1.1 dyoung PRINTREG16(regs, RTW_CRC4); 312 1.1 dyoung PRINTREG16(regs, RTW_CWR); 313 1.1 dyoung 314 1.1 dyoung /* 8-bit registers */ 315 1.1 dyoung PRINTREG8(regs, RTW_CR); 316 1.1 dyoung PRINTREG8(regs, RTW_9346CR); 317 1.1 dyoung PRINTREG8(regs, RTW_CONFIG0); 318 1.1 dyoung PRINTREG8(regs, RTW_CONFIG1); 319 1.1 dyoung PRINTREG8(regs, RTW_CONFIG2); 320 1.1 dyoung PRINTREG8(regs, RTW_MSR); 321 1.1 dyoung PRINTREG8(regs, RTW_CONFIG3); 322 1.1 dyoung PRINTREG8(regs, RTW_CONFIG4); 323 1.1 dyoung PRINTREG8(regs, RTW_TESTR); 324 1.1 dyoung PRINTREG8(regs, RTW_PSR); 325 1.1 dyoung PRINTREG8(regs, RTW_SCR); 326 1.1 dyoung PRINTREG8(regs, RTW_PHYDELAY); 327 1.1 dyoung PRINTREG8(regs, RTW_CRCOUNT); 328 1.1 dyoung PRINTREG8(regs, RTW_PHYADDR); 329 1.1 dyoung PRINTREG8(regs, RTW_PHYDATAW); 330 1.1 dyoung PRINTREG8(regs, RTW_PHYDATAR); 331 1.1 dyoung PRINTREG8(regs, RTW_CONFIG5); 332 1.1 dyoung PRINTREG8(regs, RTW_TPPOLL); 333 1.1 dyoung 334 1.1 dyoung PRINTREG16(regs, RTW_BSSID16); 335 1.1 dyoung PRINTREG32(regs, RTW_BSSID32); 336 1.1 dyoung #undef PRINTREG32 337 1.1 dyoung #undef PRINTREG16 338 1.1 dyoung #undef PRINTREG8 339 1.1 dyoung } 340 1.1 dyoung #endif /* RTW_DEBUG */ 341 1.1 dyoung 342 1.1 dyoung void 343 1.3 dyoung rtw_continuous_tx_enable(struct rtw_softc *sc, int enable) 344 1.1 dyoung { 345 1.3 dyoung struct rtw_regs *regs = &sc->sc_regs; 346 1.3 dyoung 347 1.37 dyoung uint32_t tcr; 348 1.1 dyoung tcr = RTW_READ(regs, RTW_TCR); 349 1.1 dyoung tcr &= ~RTW_TCR_LBK_MASK; 350 1.1 dyoung if (enable) 351 1.1 dyoung tcr |= RTW_TCR_LBK_CONT; 352 1.1 dyoung else 353 1.1 dyoung tcr |= RTW_TCR_LBK_NORMAL; 354 1.1 dyoung RTW_WRITE(regs, RTW_TCR, tcr); 355 1.1 dyoung RTW_SYNC(regs, RTW_TCR, RTW_TCR); 356 1.42 dyoung rtw_set_access(regs, RTW_ACCESS_ANAPARM); 357 1.4 dyoung rtw_txdac_enable(sc, !enable); 358 1.42 dyoung rtw_set_access(regs, RTW_ACCESS_ANAPARM);/* XXX Voodoo from Linux. */ 359 1.42 dyoung rtw_set_access(regs, RTW_ACCESS_NONE); 360 1.3 dyoung } 361 1.3 dyoung 362 1.24 dyoung #ifdef RTW_DEBUG 363 1.3 dyoung static const char * 364 1.3 dyoung rtw_access_string(enum rtw_access access) 365 1.3 dyoung { 366 1.3 dyoung switch (access) { 367 1.3 dyoung case RTW_ACCESS_NONE: 368 1.3 dyoung return "none"; 369 1.3 dyoung case RTW_ACCESS_CONFIG: 370 1.3 dyoung return "config"; 371 1.3 dyoung case RTW_ACCESS_ANAPARM: 372 1.3 dyoung return "anaparm"; 373 1.3 dyoung default: 374 1.3 dyoung return "unknown"; 375 1.3 dyoung } 376 1.3 dyoung } 377 1.24 dyoung #endif /* RTW_DEBUG */ 378 1.3 dyoung 379 1.3 dyoung static void 380 1.42 dyoung rtw_set_access1(struct rtw_regs *regs, enum rtw_access naccess) 381 1.3 dyoung { 382 1.76 christos KASSERT(/* naccess >= RTW_ACCESS_NONE && */ 383 1.76 christos naccess <= RTW_ACCESS_ANAPARM); 384 1.76 christos KASSERT(/* regs->r_access >= RTW_ACCESS_NONE && */ 385 1.76 christos regs->r_access <= RTW_ACCESS_ANAPARM); 386 1.3 dyoung 387 1.42 dyoung if (naccess == regs->r_access) 388 1.3 dyoung return; 389 1.3 dyoung 390 1.3 dyoung switch (naccess) { 391 1.3 dyoung case RTW_ACCESS_NONE: 392 1.42 dyoung switch (regs->r_access) { 393 1.3 dyoung case RTW_ACCESS_ANAPARM: 394 1.3 dyoung rtw_anaparm_enable(regs, 0); 395 1.3 dyoung /*FALLTHROUGH*/ 396 1.3 dyoung case RTW_ACCESS_CONFIG: 397 1.3 dyoung rtw_config0123_enable(regs, 0); 398 1.3 dyoung /*FALLTHROUGH*/ 399 1.3 dyoung case RTW_ACCESS_NONE: 400 1.3 dyoung break; 401 1.3 dyoung } 402 1.3 dyoung break; 403 1.3 dyoung case RTW_ACCESS_CONFIG: 404 1.42 dyoung switch (regs->r_access) { 405 1.3 dyoung case RTW_ACCESS_NONE: 406 1.3 dyoung rtw_config0123_enable(regs, 1); 407 1.3 dyoung /*FALLTHROUGH*/ 408 1.3 dyoung case RTW_ACCESS_CONFIG: 409 1.3 dyoung break; 410 1.3 dyoung case RTW_ACCESS_ANAPARM: 411 1.3 dyoung rtw_anaparm_enable(regs, 0); 412 1.3 dyoung break; 413 1.3 dyoung } 414 1.3 dyoung break; 415 1.3 dyoung case RTW_ACCESS_ANAPARM: 416 1.42 dyoung switch (regs->r_access) { 417 1.3 dyoung case RTW_ACCESS_NONE: 418 1.3 dyoung rtw_config0123_enable(regs, 1); 419 1.3 dyoung /*FALLTHROUGH*/ 420 1.3 dyoung case RTW_ACCESS_CONFIG: 421 1.3 dyoung rtw_anaparm_enable(regs, 1); 422 1.3 dyoung /*FALLTHROUGH*/ 423 1.3 dyoung case RTW_ACCESS_ANAPARM: 424 1.3 dyoung break; 425 1.3 dyoung } 426 1.3 dyoung break; 427 1.1 dyoung } 428 1.1 dyoung } 429 1.1 dyoung 430 1.3 dyoung void 431 1.42 dyoung rtw_set_access(struct rtw_regs *regs, enum rtw_access access) 432 1.3 dyoung { 433 1.42 dyoung rtw_set_access1(regs, access); 434 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_ACCESS, 435 1.42 dyoung ("%s: access %s -> %s\n", __func__, 436 1.42 dyoung rtw_access_string(regs->r_access), 437 1.3 dyoung rtw_access_string(access))); 438 1.42 dyoung regs->r_access = access; 439 1.3 dyoung } 440 1.3 dyoung 441 1.1 dyoung /* 442 1.1 dyoung * Enable registers, switch register banks. 443 1.1 dyoung */ 444 1.1 dyoung void 445 1.1 dyoung rtw_config0123_enable(struct rtw_regs *regs, int enable) 446 1.1 dyoung { 447 1.37 dyoung uint8_t ecr; 448 1.1 dyoung ecr = RTW_READ8(regs, RTW_9346CR); 449 1.1 dyoung ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK); 450 1.1 dyoung if (enable) 451 1.1 dyoung ecr |= RTW_9346CR_EEM_CONFIG; 452 1.8 dyoung else { 453 1.8 dyoung RTW_WBW(regs, RTW_9346CR, MAX(RTW_CONFIG0, RTW_CONFIG3)); 454 1.1 dyoung ecr |= RTW_9346CR_EEM_NORMAL; 455 1.8 dyoung } 456 1.1 dyoung RTW_WRITE8(regs, RTW_9346CR, ecr); 457 1.1 dyoung RTW_SYNC(regs, RTW_9346CR, RTW_9346CR); 458 1.1 dyoung } 459 1.1 dyoung 460 1.1 dyoung /* requires rtw_config0123_enable(, 1) */ 461 1.1 dyoung void 462 1.1 dyoung rtw_anaparm_enable(struct rtw_regs *regs, int enable) 463 1.1 dyoung { 464 1.37 dyoung uint8_t cfg3; 465 1.1 dyoung 466 1.1 dyoung cfg3 = RTW_READ8(regs, RTW_CONFIG3); 467 1.3 dyoung cfg3 |= RTW_CONFIG3_CLKRUNEN; 468 1.3 dyoung if (enable) 469 1.3 dyoung cfg3 |= RTW_CONFIG3_PARMEN; 470 1.3 dyoung else 471 1.1 dyoung cfg3 &= ~RTW_CONFIG3_PARMEN; 472 1.1 dyoung RTW_WRITE8(regs, RTW_CONFIG3, cfg3); 473 1.1 dyoung RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3); 474 1.1 dyoung } 475 1.1 dyoung 476 1.1 dyoung /* requires rtw_anaparm_enable(, 1) */ 477 1.1 dyoung void 478 1.4 dyoung rtw_txdac_enable(struct rtw_softc *sc, int enable) 479 1.1 dyoung { 480 1.37 dyoung uint32_t anaparm; 481 1.4 dyoung struct rtw_regs *regs = &sc->sc_regs; 482 1.1 dyoung 483 1.1 dyoung anaparm = RTW_READ(regs, RTW_ANAPARM); 484 1.1 dyoung if (enable) 485 1.1 dyoung anaparm &= ~RTW_ANAPARM_TXDACOFF; 486 1.1 dyoung else 487 1.1 dyoung anaparm |= RTW_ANAPARM_TXDACOFF; 488 1.1 dyoung RTW_WRITE(regs, RTW_ANAPARM, anaparm); 489 1.1 dyoung RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 490 1.1 dyoung } 491 1.1 dyoung 492 1.61 perry static inline int 493 1.98 dyoung rtw_chip_reset1(struct rtw_regs *regs, device_t dev) 494 1.1 dyoung { 495 1.37 dyoung uint8_t cr; 496 1.1 dyoung int i; 497 1.1 dyoung 498 1.1 dyoung RTW_WRITE8(regs, RTW_CR, RTW_CR_RST); 499 1.1 dyoung 500 1.1 dyoung RTW_WBR(regs, RTW_CR, RTW_CR); 501 1.1 dyoung 502 1.21 dyoung for (i = 0; i < 1000; i++) { 503 1.1 dyoung if ((cr = RTW_READ8(regs, RTW_CR) & RTW_CR_RST) == 0) { 504 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_RESET, 505 1.98 dyoung ("%s: reset in %dus\n", device_xname(dev), i)); 506 1.1 dyoung return 0; 507 1.1 dyoung } 508 1.1 dyoung RTW_RBR(regs, RTW_CR, RTW_CR); 509 1.21 dyoung DELAY(10); /* 10us */ 510 1.1 dyoung } 511 1.1 dyoung 512 1.98 dyoung aprint_error_dev(dev, "reset failed\n"); 513 1.1 dyoung return ETIMEDOUT; 514 1.1 dyoung } 515 1.1 dyoung 516 1.61 perry static inline int 517 1.98 dyoung rtw_chip_reset(struct rtw_regs *regs, device_t dev) 518 1.3 dyoung { 519 1.3 dyoung uint32_t tcr; 520 1.3 dyoung 521 1.3 dyoung /* from Linux driver */ 522 1.3 dyoung tcr = RTW_TCR_CWMIN | RTW_TCR_MXDMA_2048 | 523 1.75 dyoung __SHIFTIN(7, RTW_TCR_SRL_MASK) | __SHIFTIN(7, RTW_TCR_LRL_MASK); 524 1.3 dyoung 525 1.3 dyoung RTW_WRITE(regs, RTW_TCR, tcr); 526 1.3 dyoung 527 1.3 dyoung RTW_WBW(regs, RTW_CR, RTW_TCR); 528 1.3 dyoung 529 1.98 dyoung return rtw_chip_reset1(regs, dev); 530 1.3 dyoung } 531 1.3 dyoung 532 1.49 dyoung static int 533 1.58 dyoung rtw_wep_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen) 534 1.50 dyoung { 535 1.50 dyoung struct ieee80211_key keycopy; 536 1.50 dyoung 537 1.50 dyoung RTW_DPRINTF(RTW_DEBUG_KEY, ("%s:\n", __func__)); 538 1.50 dyoung 539 1.50 dyoung keycopy = *k; 540 1.50 dyoung keycopy.wk_flags &= ~IEEE80211_KEY_SWCRYPT; 541 1.50 dyoung 542 1.58 dyoung return (*ieee80211_cipher_wep.ic_decap)(&keycopy, m, hdrlen); 543 1.50 dyoung } 544 1.50 dyoung 545 1.50 dyoung static int 546 1.49 dyoung rtw_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k) 547 1.49 dyoung { 548 1.49 dyoung struct rtw_softc *sc = ic->ic_ifp->if_softc; 549 1.49 dyoung 550 1.102 dyoung DPRINTF(sc, RTW_DEBUG_KEY, ("%s: delete key %u\n", __func__, 551 1.102 dyoung k->wk_keyix)); 552 1.49 dyoung 553 1.102 dyoung KASSERT(k->wk_keyix < IEEE80211_WEP_NKID); 554 1.102 dyoung 555 1.102 dyoung if (k->wk_keylen != 0 && 556 1.102 dyoung k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP) 557 1.49 dyoung sc->sc_flags &= ~RTW_F_DK_VALID; 558 1.49 dyoung 559 1.49 dyoung return 1; 560 1.49 dyoung } 561 1.49 dyoung 562 1.49 dyoung static int 563 1.49 dyoung rtw_key_set(struct ieee80211com *ic, const struct ieee80211_key *k, 564 1.131 msaitoh const uint8_t mac[IEEE80211_ADDR_LEN]) 565 1.49 dyoung { 566 1.49 dyoung struct rtw_softc *sc = ic->ic_ifp->if_softc; 567 1.49 dyoung 568 1.49 dyoung DPRINTF(sc, RTW_DEBUG_KEY, ("%s: set key %u\n", __func__, k->wk_keyix)); 569 1.49 dyoung 570 1.102 dyoung KASSERT(k->wk_keyix < IEEE80211_WEP_NKID); 571 1.49 dyoung 572 1.49 dyoung sc->sc_flags &= ~RTW_F_DK_VALID; 573 1.49 dyoung 574 1.49 dyoung return 1; 575 1.49 dyoung } 576 1.49 dyoung 577 1.49 dyoung static void 578 1.81 christos rtw_key_update_begin(struct ieee80211com *ic) 579 1.49 dyoung { 580 1.55 dogcow #ifdef RTW_DEBUG 581 1.49 dyoung struct ifnet *ifp = ic->ic_ifp; 582 1.49 dyoung struct rtw_softc *sc = ifp->if_softc; 583 1.49 dyoung #endif 584 1.49 dyoung 585 1.49 dyoung DPRINTF(sc, RTW_DEBUG_KEY, ("%s:\n", __func__)); 586 1.49 dyoung } 587 1.49 dyoung 588 1.49 dyoung static void 589 1.103 dyoung rtw_tx_kick(struct rtw_regs *regs, uint8_t ringsel) 590 1.103 dyoung { 591 1.103 dyoung uint8_t tppoll; 592 1.103 dyoung 593 1.103 dyoung tppoll = RTW_READ8(regs, RTW_TPPOLL); 594 1.103 dyoung tppoll &= ~RTW_TPPOLL_SALL; 595 1.103 dyoung tppoll |= ringsel & RTW_TPPOLL_ALL; 596 1.103 dyoung RTW_WRITE8(regs, RTW_TPPOLL, tppoll); 597 1.103 dyoung RTW_SYNC(regs, RTW_TPPOLL, RTW_TPPOLL); 598 1.103 dyoung } 599 1.103 dyoung 600 1.103 dyoung static void 601 1.49 dyoung rtw_key_update_end(struct ieee80211com *ic) 602 1.49 dyoung { 603 1.49 dyoung struct ifnet *ifp = ic->ic_ifp; 604 1.49 dyoung struct rtw_softc *sc = ifp->if_softc; 605 1.49 dyoung 606 1.49 dyoung DPRINTF(sc, RTW_DEBUG_KEY, ("%s:\n", __func__)); 607 1.49 dyoung 608 1.58 dyoung if ((sc->sc_flags & RTW_F_DK_VALID) != 0 || 609 1.101 dyoung !device_is_active(sc->sc_dev)) 610 1.49 dyoung return; 611 1.49 dyoung 612 1.83 dyoung rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0); 613 1.49 dyoung rtw_wep_setkeys(sc, ic->ic_nw_keys, ic->ic_def_txkey); 614 1.83 dyoung rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 615 1.49 dyoung (ifp->if_flags & IFF_RUNNING) != 0); 616 1.49 dyoung } 617 1.49 dyoung 618 1.104 dyoung static bool 619 1.58 dyoung rtw_key_hwsupp(uint32_t flags, const struct ieee80211_key *k) 620 1.58 dyoung { 621 1.58 dyoung if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP) 622 1.104 dyoung return false; 623 1.58 dyoung 624 1.58 dyoung return ((flags & RTW_C_RXWEP_40) != 0 && k->wk_keylen == 5) || 625 1.58 dyoung ((flags & RTW_C_RXWEP_104) != 0 && k->wk_keylen == 13); 626 1.58 dyoung } 627 1.58 dyoung 628 1.42 dyoung static void 629 1.48 dyoung rtw_wep_setkeys(struct rtw_softc *sc, struct ieee80211_key *wk, int txkey) 630 1.42 dyoung { 631 1.58 dyoung uint8_t psr, scr; 632 1.104 dyoung int i, keylen = 0; 633 1.42 dyoung struct rtw_regs *regs; 634 1.42 dyoung union rtw_keys *rk; 635 1.42 dyoung 636 1.42 dyoung regs = &sc->sc_regs; 637 1.42 dyoung rk = &sc->sc_keys; 638 1.42 dyoung 639 1.119 joerg (void)memset(rk, 0, sizeof(*rk)); 640 1.42 dyoung 641 1.58 dyoung /* Temporarily use software crypto for all keys. */ 642 1.58 dyoung for (i = 0; i < IEEE80211_WEP_NKID; i++) { 643 1.58 dyoung if (wk[i].wk_cipher == &rtw_cipher_wep) 644 1.58 dyoung wk[i].wk_cipher = &ieee80211_cipher_wep; 645 1.58 dyoung } 646 1.58 dyoung 647 1.50 dyoung rtw_set_access(regs, RTW_ACCESS_CONFIG); 648 1.50 dyoung 649 1.50 dyoung psr = RTW_READ8(regs, RTW_PSR); 650 1.42 dyoung scr = RTW_READ8(regs, RTW_SCR); 651 1.42 dyoung scr &= ~(RTW_SCR_KM_MASK | RTW_SCR_TXSECON | RTW_SCR_RXSECON); 652 1.42 dyoung 653 1.42 dyoung if ((sc->sc_ic.ic_flags & IEEE80211_F_PRIVACY) == 0) 654 1.42 dyoung goto out; 655 1.42 dyoung 656 1.104 dyoung for (i = 0; i < IEEE80211_WEP_NKID; i++) { 657 1.66 dyoung if (!rtw_key_hwsupp(sc->sc_flags, &wk[i])) 658 1.66 dyoung continue; 659 1.66 dyoung if (i == txkey) { 660 1.66 dyoung keylen = wk[i].wk_keylen; 661 1.66 dyoung break; 662 1.66 dyoung } 663 1.66 dyoung keylen = MAX(keylen, wk[i].wk_keylen); 664 1.42 dyoung } 665 1.42 dyoung 666 1.66 dyoung if (keylen == 5) 667 1.66 dyoung scr |= RTW_SCR_KM_WEP40 | RTW_SCR_RXSECON; 668 1.66 dyoung else if (keylen == 13) 669 1.66 dyoung scr |= RTW_SCR_KM_WEP104 | RTW_SCR_RXSECON; 670 1.42 dyoung 671 1.49 dyoung for (i = 0; i < IEEE80211_WEP_NKID; i++) { 672 1.66 dyoung if (wk[i].wk_keylen != keylen || 673 1.58 dyoung wk[i].wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP) 674 1.42 dyoung continue; 675 1.58 dyoung /* h/w will decrypt, s/w still strips headers */ 676 1.58 dyoung wk[i].wk_cipher = &rtw_cipher_wep; 677 1.49 dyoung (void)memcpy(rk->rk_keys[i], wk[i].wk_key, wk[i].wk_keylen); 678 1.42 dyoung } 679 1.42 dyoung 680 1.42 dyoung out: 681 1.50 dyoung RTW_WRITE8(regs, RTW_PSR, psr & ~RTW_PSR_PSEN); 682 1.50 dyoung 683 1.88 dyoung bus_space_write_region_stream_4(regs->r_bt, regs->r_bh, 684 1.87 dyoung RTW_DK0, rk->rk_words, __arraycount(rk->rk_words)); 685 1.42 dyoung 686 1.50 dyoung bus_space_barrier(regs->r_bt, regs->r_bh, RTW_DK0, sizeof(rk->rk_words), 687 1.131 msaitoh BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 688 1.42 dyoung 689 1.104 dyoung RTW_DPRINTF(RTW_DEBUG_KEY, 690 1.104 dyoung ("%s.%d: scr %02" PRIx8 ", keylen %d\n", __func__, __LINE__, scr, 691 1.104 dyoung keylen)); 692 1.104 dyoung 693 1.58 dyoung RTW_WBW(regs, RTW_DK0, RTW_PSR); 694 1.50 dyoung RTW_WRITE8(regs, RTW_PSR, psr); 695 1.58 dyoung RTW_WBW(regs, RTW_PSR, RTW_SCR); 696 1.42 dyoung RTW_WRITE8(regs, RTW_SCR, scr); 697 1.42 dyoung RTW_SYNC(regs, RTW_SCR, RTW_SCR); 698 1.42 dyoung rtw_set_access(regs, RTW_ACCESS_NONE); 699 1.49 dyoung sc->sc_flags |= RTW_F_DK_VALID; 700 1.42 dyoung } 701 1.42 dyoung 702 1.61 perry static inline int 703 1.98 dyoung rtw_recall_eeprom(struct rtw_regs *regs, device_t dev) 704 1.1 dyoung { 705 1.1 dyoung int i; 706 1.37 dyoung uint8_t ecr; 707 1.1 dyoung 708 1.1 dyoung ecr = RTW_READ8(regs, RTW_9346CR); 709 1.1 dyoung ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD; 710 1.1 dyoung RTW_WRITE8(regs, RTW_9346CR, ecr); 711 1.1 dyoung 712 1.1 dyoung RTW_WBR(regs, RTW_9346CR, RTW_9346CR); 713 1.1 dyoung 714 1.55 dogcow /* wait 25ms for completion */ 715 1.55 dogcow for (i = 0; i < 250; i++) { 716 1.1 dyoung ecr = RTW_READ8(regs, RTW_9346CR); 717 1.1 dyoung if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) { 718 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_RESET, 719 1.98 dyoung ("%s: recall EEPROM in %dus\n", device_xname(dev), 720 1.98 dyoung i * 100)); 721 1.1 dyoung return 0; 722 1.1 dyoung } 723 1.1 dyoung RTW_RBR(regs, RTW_9346CR, RTW_9346CR); 724 1.1 dyoung DELAY(100); 725 1.1 dyoung } 726 1.98 dyoung aprint_error_dev(dev, "recall EEPROM failed\n"); 727 1.1 dyoung return ETIMEDOUT; 728 1.1 dyoung } 729 1.1 dyoung 730 1.61 perry static inline int 731 1.1 dyoung rtw_reset(struct rtw_softc *sc) 732 1.1 dyoung { 733 1.1 dyoung int rc; 734 1.4 dyoung uint8_t config1; 735 1.1 dyoung 736 1.49 dyoung sc->sc_flags &= ~RTW_F_DK_VALID; 737 1.49 dyoung 738 1.98 dyoung if ((rc = rtw_chip_reset(&sc->sc_regs, sc->sc_dev)) != 0) 739 1.1 dyoung return rc; 740 1.1 dyoung 741 1.98 dyoung rc = rtw_recall_eeprom(&sc->sc_regs, sc->sc_dev); 742 1.1 dyoung 743 1.4 dyoung config1 = RTW_READ8(&sc->sc_regs, RTW_CONFIG1); 744 1.4 dyoung RTW_WRITE8(&sc->sc_regs, RTW_CONFIG1, config1 & ~RTW_CONFIG1_PMEN); 745 1.1 dyoung /* TBD turn off maximum power saving? */ 746 1.1 dyoung 747 1.1 dyoung return 0; 748 1.1 dyoung } 749 1.1 dyoung 750 1.61 perry static inline int 751 1.34 dyoung rtw_txdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_txsoft *descs, 752 1.1 dyoung u_int ndescs) 753 1.1 dyoung { 754 1.1 dyoung int i, rc = 0; 755 1.1 dyoung for (i = 0; i < ndescs; i++) { 756 1.1 dyoung rc = bus_dmamap_create(dmat, MCLBYTES, RTW_MAXPKTSEGS, MCLBYTES, 757 1.34 dyoung 0, 0, &descs[i].ts_dmamap); 758 1.1 dyoung if (rc != 0) 759 1.1 dyoung break; 760 1.1 dyoung } 761 1.1 dyoung return rc; 762 1.1 dyoung } 763 1.1 dyoung 764 1.61 perry static inline int 765 1.34 dyoung rtw_rxdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_rxsoft *descs, 766 1.1 dyoung u_int ndescs) 767 1.1 dyoung { 768 1.1 dyoung int i, rc = 0; 769 1.1 dyoung for (i = 0; i < ndescs; i++) { 770 1.1 dyoung rc = bus_dmamap_create(dmat, MCLBYTES, 1, MCLBYTES, 0, 0, 771 1.34 dyoung &descs[i].rs_dmamap); 772 1.1 dyoung if (rc != 0) 773 1.1 dyoung break; 774 1.1 dyoung } 775 1.1 dyoung return rc; 776 1.1 dyoung } 777 1.1 dyoung 778 1.61 perry static inline void 779 1.34 dyoung rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_rxsoft *descs, 780 1.1 dyoung u_int ndescs) 781 1.1 dyoung { 782 1.1 dyoung int i; 783 1.1 dyoung for (i = 0; i < ndescs; i++) { 784 1.34 dyoung if (descs[i].rs_dmamap != NULL) 785 1.34 dyoung bus_dmamap_destroy(dmat, descs[i].rs_dmamap); 786 1.1 dyoung } 787 1.1 dyoung } 788 1.1 dyoung 789 1.61 perry static inline void 790 1.34 dyoung rtw_txdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_txsoft *descs, 791 1.1 dyoung u_int ndescs) 792 1.1 dyoung { 793 1.1 dyoung int i; 794 1.1 dyoung for (i = 0; i < ndescs; i++) { 795 1.34 dyoung if (descs[i].ts_dmamap != NULL) 796 1.34 dyoung bus_dmamap_destroy(dmat, descs[i].ts_dmamap); 797 1.1 dyoung } 798 1.1 dyoung } 799 1.1 dyoung 800 1.61 perry static inline void 801 1.1 dyoung rtw_srom_free(struct rtw_srom *sr) 802 1.1 dyoung { 803 1.1 dyoung sr->sr_size = 0; 804 1.1 dyoung if (sr->sr_content == NULL) 805 1.1 dyoung return; 806 1.1 dyoung free(sr->sr_content, M_DEVBUF); 807 1.1 dyoung sr->sr_content = NULL; 808 1.1 dyoung } 809 1.1 dyoung 810 1.1 dyoung static void 811 1.81 christos rtw_srom_defaults(struct rtw_srom *sr, uint32_t *flags, 812 1.78 christos uint8_t *cs_threshold, enum rtw_rfchipid *rfchipid, uint32_t *rcr) 813 1.1 dyoung { 814 1.131 msaitoh *flags |= (RTW_F_DIGPHY | RTW_F_ANTDIV); 815 1.1 dyoung *cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT; 816 1.1 dyoung *rcr |= RTW_RCR_ENCS1; 817 1.1 dyoung *rfchipid = RTW_RFCHIPID_PHILIPS; 818 1.1 dyoung } 819 1.1 dyoung 820 1.1 dyoung static int 821 1.37 dyoung rtw_srom_parse(struct rtw_srom *sr, uint32_t *flags, uint8_t *cs_threshold, 822 1.37 dyoung enum rtw_rfchipid *rfchipid, uint32_t *rcr, enum rtw_locale *locale, 823 1.98 dyoung device_t dev) 824 1.1 dyoung { 825 1.1 dyoung int i; 826 1.1 dyoung const char *rfname, *paname; 827 1.1 dyoung char scratch[sizeof("unknown 0xXX")]; 828 1.46 dyoung uint16_t srom_version; 829 1.1 dyoung 830 1.131 msaitoh *flags &= ~(RTW_F_DIGPHY | RTW_F_DFLANTB | RTW_F_ANTDIV); 831 1.1 dyoung *rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2); 832 1.1 dyoung 833 1.46 dyoung srom_version = RTW_SR_GET16(sr, RTW_SR_VERSION); 834 1.1 dyoung 835 1.46 dyoung if (srom_version <= 0x0101) { 836 1.98 dyoung aprint_error_dev(dev, 837 1.98 dyoung "SROM version %d.%d is not understood, " 838 1.98 dyoung "limping along with defaults\n", 839 1.98 dyoung srom_version >> 8, srom_version & 0xff); 840 1.7 dyoung rtw_srom_defaults(sr, flags, cs_threshold, rfchipid, rcr); 841 1.1 dyoung return 0; 842 1.98 dyoung } else { 843 1.113 dyoung aprint_verbose_dev(dev, "SROM version %d.%d\n", 844 1.98 dyoung srom_version >> 8, srom_version & 0xff); 845 1.1 dyoung } 846 1.1 dyoung 847 1.120 christos uint8_t mac[IEEE80211_ADDR_LEN]; 848 1.1 dyoung for (i = 0; i < IEEE80211_ADDR_LEN; i++) 849 1.1 dyoung mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i); 850 1.120 christos __USE(mac); 851 1.1 dyoung 852 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_ATTACH, 853 1.98 dyoung ("%s: EEPROM MAC %s\n", device_xname(dev), ether_sprintf(mac))); 854 1.1 dyoung 855 1.1 dyoung *cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR); 856 1.1 dyoung 857 1.1 dyoung if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW_CONFIG2_ANT) != 0) 858 1.1 dyoung *flags |= RTW_F_ANTDIV; 859 1.1 dyoung 860 1.10 dyoung /* Note well: the sense of the RTW_SR_RFPARM_DIGPHY bit seems 861 1.10 dyoung * to be reversed. 862 1.10 dyoung */ 863 1.10 dyoung if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) == 0) 864 1.1 dyoung *flags |= RTW_F_DIGPHY; 865 1.1 dyoung if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0) 866 1.1 dyoung *flags |= RTW_F_DFLANTB; 867 1.1 dyoung 868 1.75 dyoung *rcr |= __SHIFTIN(__SHIFTOUT(RTW_SR_GET(sr, RTW_SR_RFPARM), 869 1.1 dyoung RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1); 870 1.1 dyoung 871 1.58 dyoung if ((RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_WEP104) != 0) 872 1.58 dyoung *flags |= RTW_C_RXWEP_104; 873 1.58 dyoung 874 1.58 dyoung *flags |= RTW_C_RXWEP_40; /* XXX */ 875 1.58 dyoung 876 1.1 dyoung *rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID); 877 1.1 dyoung switch (*rfchipid) { 878 1.1 dyoung case RTW_RFCHIPID_GCT: /* this combo seen in the wild */ 879 1.1 dyoung rfname = "GCT GRF5101"; 880 1.1 dyoung paname = "Winspring WS9901"; 881 1.1 dyoung break; 882 1.1 dyoung case RTW_RFCHIPID_MAXIM: 883 1.1 dyoung rfname = "Maxim MAX2820"; /* guess */ 884 1.1 dyoung paname = "Maxim MAX2422"; /* guess */ 885 1.1 dyoung break; 886 1.1 dyoung case RTW_RFCHIPID_INTERSIL: 887 1.1 dyoung rfname = "Intersil HFA3873"; /* guess */ 888 1.1 dyoung paname = "Intersil <unknown>"; 889 1.1 dyoung break; 890 1.1 dyoung case RTW_RFCHIPID_PHILIPS: /* this combo seen in the wild */ 891 1.1 dyoung rfname = "Philips SA2400A"; 892 1.1 dyoung paname = "Philips SA2411"; 893 1.1 dyoung break; 894 1.1 dyoung case RTW_RFCHIPID_RFMD: 895 1.1 dyoung /* this is the same front-end as an atw(4)! */ 896 1.1 dyoung rfname = "RFMD RF2948B, " /* mentioned in Realtek docs */ 897 1.1 dyoung "LNA: RFMD RF2494, " /* mentioned in Realtek docs */ 898 1.1 dyoung "SYN: Silicon Labs Si4126"; /* inferred from 899 1.132 msaitoh * reference driver 900 1.1 dyoung */ 901 1.1 dyoung paname = "RFMD RF2189"; /* mentioned in Realtek docs */ 902 1.1 dyoung break; 903 1.1 dyoung case RTW_RFCHIPID_RESERVED: 904 1.1 dyoung rfname = paname = "reserved"; 905 1.1 dyoung break; 906 1.1 dyoung default: 907 1.1 dyoung snprintf(scratch, sizeof(scratch), "unknown 0x%02x", *rfchipid); 908 1.1 dyoung rfname = paname = scratch; 909 1.1 dyoung } 910 1.98 dyoung aprint_normal_dev(dev, "RF: %s, PA: %s\n", rfname, paname); 911 1.1 dyoung 912 1.1 dyoung switch (RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_GL_MASK) { 913 1.1 dyoung case RTW_CONFIG0_GL_USA: 914 1.55 dogcow case _RTW_CONFIG0_GL_USA: 915 1.1 dyoung *locale = RTW_LOCALE_USA; 916 1.1 dyoung break; 917 1.1 dyoung case RTW_CONFIG0_GL_EUROPE: 918 1.1 dyoung *locale = RTW_LOCALE_EUROPE; 919 1.1 dyoung break; 920 1.1 dyoung case RTW_CONFIG0_GL_JAPAN: 921 1.1 dyoung *locale = RTW_LOCALE_JAPAN; 922 1.1 dyoung break; 923 1.1 dyoung default: 924 1.1 dyoung *locale = RTW_LOCALE_UNKNOWN; 925 1.1 dyoung break; 926 1.1 dyoung } 927 1.1 dyoung return 0; 928 1.1 dyoung } 929 1.1 dyoung 930 1.1 dyoung /* Returns -1 on failure. */ 931 1.1 dyoung static int 932 1.37 dyoung rtw_srom_read(struct rtw_regs *regs, uint32_t flags, struct rtw_srom *sr, 933 1.98 dyoung device_t dev) 934 1.1 dyoung { 935 1.1 dyoung int rc; 936 1.1 dyoung struct seeprom_descriptor sd; 937 1.37 dyoung uint8_t ecr; 938 1.1 dyoung 939 1.1 dyoung (void)memset(&sd, 0, sizeof(sd)); 940 1.1 dyoung 941 1.1 dyoung ecr = RTW_READ8(regs, RTW_9346CR); 942 1.1 dyoung 943 1.1 dyoung if ((flags & RTW_F_9356SROM) != 0) { 944 1.98 dyoung RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c56 SROM\n", 945 1.98 dyoung device_xname(dev))); 946 1.1 dyoung sr->sr_size = 256; 947 1.1 dyoung sd.sd_chip = C56_66; 948 1.1 dyoung } else { 949 1.98 dyoung RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c46 SROM\n", 950 1.98 dyoung device_xname(dev))); 951 1.1 dyoung sr->sr_size = 128; 952 1.1 dyoung sd.sd_chip = C46; 953 1.1 dyoung } 954 1.1 dyoung 955 1.1 dyoung ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK | 956 1.41 dyoung RTW_9346CR_EEM_MASK | RTW_9346CR_EECS); 957 1.1 dyoung ecr |= RTW_9346CR_EEM_PROGRAM; 958 1.1 dyoung 959 1.1 dyoung RTW_WRITE8(regs, RTW_9346CR, ecr); 960 1.1 dyoung 961 1.134 chs sr->sr_content = malloc(sr->sr_size, M_DEVBUF, M_WAITOK | M_ZERO); 962 1.1 dyoung 963 1.1 dyoung /* RTL8180 has a single 8-bit register for controlling the 964 1.1 dyoung * 93cx6 SROM. There is no "ready" bit. The RTL8180 965 1.1 dyoung * input/output sense is the reverse of read_seeprom's. 966 1.1 dyoung */ 967 1.1 dyoung sd.sd_tag = regs->r_bt; 968 1.1 dyoung sd.sd_bsh = regs->r_bh; 969 1.1 dyoung sd.sd_regsize = 1; 970 1.1 dyoung sd.sd_control_offset = RTW_9346CR; 971 1.1 dyoung sd.sd_status_offset = RTW_9346CR; 972 1.1 dyoung sd.sd_dataout_offset = RTW_9346CR; 973 1.1 dyoung sd.sd_CK = RTW_9346CR_EESK; 974 1.1 dyoung sd.sd_CS = RTW_9346CR_EECS; 975 1.1 dyoung sd.sd_DI = RTW_9346CR_EEDO; 976 1.1 dyoung sd.sd_DO = RTW_9346CR_EEDI; 977 1.44 perry /* make read_seeprom enter EEPROM read/write mode */ 978 1.1 dyoung sd.sd_MS = ecr; 979 1.1 dyoung sd.sd_RDY = 0; 980 1.1 dyoung 981 1.8 dyoung /* TBD bus barriers */ 982 1.1 dyoung if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) { 983 1.98 dyoung aprint_error_dev(dev, "could not read SROM\n"); 984 1.1 dyoung free(sr->sr_content, M_DEVBUF); 985 1.1 dyoung sr->sr_content = NULL; 986 1.1 dyoung return -1; /* XXX */ 987 1.1 dyoung } 988 1.1 dyoung 989 1.44 perry /* end EEPROM read/write mode */ 990 1.1 dyoung RTW_WRITE8(regs, RTW_9346CR, 991 1.1 dyoung (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL); 992 1.1 dyoung RTW_WBRW(regs, RTW_9346CR, RTW_9346CR); 993 1.1 dyoung 994 1.98 dyoung if ((rc = rtw_recall_eeprom(regs, dev)) != 0) 995 1.1 dyoung return rc; 996 1.1 dyoung 997 1.1 dyoung #ifdef RTW_DEBUG 998 1.1 dyoung { 999 1.1 dyoung int i; 1000 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_ATTACH, 1001 1.98 dyoung ("\n%s: serial ROM:\n\t", device_xname(dev))); 1002 1.1 dyoung for (i = 0; i < sr->sr_size/2; i++) { 1003 1.1 dyoung if (((i % 8) == 0) && (i != 0)) 1004 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n\t")); 1005 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_ATTACH, 1006 1.21 dyoung (" %04x", sr->sr_content[i])); 1007 1.1 dyoung } 1008 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n")); 1009 1.1 dyoung } 1010 1.1 dyoung #endif /* RTW_DEBUG */ 1011 1.1 dyoung return 0; 1012 1.1 dyoung } 1013 1.1 dyoung 1014 1.4 dyoung static void 1015 1.4 dyoung rtw_set_rfprog(struct rtw_regs *regs, enum rtw_rfchipid rfchipid, 1016 1.98 dyoung device_t dev) 1017 1.4 dyoung { 1018 1.37 dyoung uint8_t cfg4; 1019 1.4 dyoung const char *method; 1020 1.4 dyoung 1021 1.4 dyoung cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK; 1022 1.4 dyoung 1023 1.4 dyoung switch (rfchipid) { 1024 1.4 dyoung default: 1025 1.75 dyoung cfg4 |= __SHIFTIN(rtw_rfprog_fallback, RTW_CONFIG4_RFTYPE_MASK); 1026 1.4 dyoung method = "fallback"; 1027 1.4 dyoung break; 1028 1.4 dyoung case RTW_RFCHIPID_INTERSIL: 1029 1.4 dyoung cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL; 1030 1.4 dyoung method = "Intersil"; 1031 1.4 dyoung break; 1032 1.4 dyoung case RTW_RFCHIPID_PHILIPS: 1033 1.4 dyoung cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS; 1034 1.4 dyoung method = "Philips"; 1035 1.4 dyoung break; 1036 1.42 dyoung case RTW_RFCHIPID_GCT: /* XXX a guess */ 1037 1.4 dyoung case RTW_RFCHIPID_RFMD: 1038 1.4 dyoung cfg4 |= RTW_CONFIG4_RFTYPE_RFMD; 1039 1.4 dyoung method = "RFMD"; 1040 1.4 dyoung break; 1041 1.4 dyoung } 1042 1.4 dyoung 1043 1.4 dyoung RTW_WRITE8(regs, RTW_CONFIG4, cfg4); 1044 1.4 dyoung 1045 1.8 dyoung RTW_WBR(regs, RTW_CONFIG4, RTW_CONFIG4); 1046 1.8 dyoung 1047 1.120 christos #ifdef RTW_DEBUG 1048 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_INIT, 1049 1.98 dyoung ("%s: %s RF programming method, %#02x\n", device_xname(dev), method, 1050 1.10 dyoung RTW_READ8(regs, RTW_CONFIG4))); 1051 1.120 christos #else 1052 1.120 christos __USE(method); 1053 1.120 christos #endif 1054 1.4 dyoung } 1055 1.4 dyoung 1056 1.61 perry static inline void 1057 1.1 dyoung rtw_init_channels(enum rtw_locale locale, 1058 1.98 dyoung struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1], device_t dev) 1059 1.1 dyoung { 1060 1.1 dyoung int i; 1061 1.1 dyoung const char *name = NULL; 1062 1.1 dyoung #define ADD_CHANNEL(_chans, _chan) do { \ 1063 1.1 dyoung (*_chans)[_chan].ic_flags = IEEE80211_CHAN_B; \ 1064 1.1 dyoung (*_chans)[_chan].ic_freq = \ 1065 1.1 dyoung ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ic_flags);\ 1066 1.1 dyoung } while (0) 1067 1.1 dyoung 1068 1.1 dyoung switch (locale) { 1069 1.1 dyoung case RTW_LOCALE_USA: /* 1-11 */ 1070 1.1 dyoung name = "USA"; 1071 1.1 dyoung for (i = 1; i <= 11; i++) 1072 1.1 dyoung ADD_CHANNEL(chans, i); 1073 1.1 dyoung break; 1074 1.1 dyoung case RTW_LOCALE_JAPAN: /* 1-14 */ 1075 1.1 dyoung name = "Japan"; 1076 1.1 dyoung ADD_CHANNEL(chans, 14); 1077 1.1 dyoung for (i = 1; i <= 14; i++) 1078 1.1 dyoung ADD_CHANNEL(chans, i); 1079 1.1 dyoung break; 1080 1.1 dyoung case RTW_LOCALE_EUROPE: /* 1-13 */ 1081 1.1 dyoung name = "Europe"; 1082 1.1 dyoung for (i = 1; i <= 13; i++) 1083 1.1 dyoung ADD_CHANNEL(chans, i); 1084 1.1 dyoung break; 1085 1.1 dyoung default: /* 10-11 allowed by most countries */ 1086 1.1 dyoung name = "<unknown>"; 1087 1.1 dyoung for (i = 10; i <= 11; i++) 1088 1.1 dyoung ADD_CHANNEL(chans, i); 1089 1.1 dyoung break; 1090 1.1 dyoung } 1091 1.98 dyoung aprint_normal_dev(dev, "Geographic Location %s\n", name); 1092 1.1 dyoung #undef ADD_CHANNEL 1093 1.1 dyoung } 1094 1.1 dyoung 1095 1.58 dyoung 1096 1.61 perry static inline void 1097 1.58 dyoung rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale) 1098 1.1 dyoung { 1099 1.37 dyoung uint8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0); 1100 1.1 dyoung 1101 1.1 dyoung switch (cfg0 & RTW_CONFIG0_GL_MASK) { 1102 1.1 dyoung case RTW_CONFIG0_GL_USA: 1103 1.55 dogcow case _RTW_CONFIG0_GL_USA: 1104 1.1 dyoung *locale = RTW_LOCALE_USA; 1105 1.1 dyoung break; 1106 1.1 dyoung case RTW_CONFIG0_GL_JAPAN: 1107 1.1 dyoung *locale = RTW_LOCALE_JAPAN; 1108 1.1 dyoung break; 1109 1.1 dyoung case RTW_CONFIG0_GL_EUROPE: 1110 1.1 dyoung *locale = RTW_LOCALE_EUROPE; 1111 1.1 dyoung break; 1112 1.1 dyoung default: 1113 1.1 dyoung *locale = RTW_LOCALE_UNKNOWN; 1114 1.1 dyoung break; 1115 1.1 dyoung } 1116 1.1 dyoung } 1117 1.1 dyoung 1118 1.61 perry static inline int 1119 1.37 dyoung rtw_identify_sta(struct rtw_regs *regs, uint8_t (*addr)[IEEE80211_ADDR_LEN], 1120 1.98 dyoung device_t dev) 1121 1.1 dyoung { 1122 1.37 dyoung static const uint8_t empty_macaddr[IEEE80211_ADDR_LEN] = { 1123 1.1 dyoung 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 1124 1.1 dyoung }; 1125 1.37 dyoung uint32_t idr0 = RTW_READ(regs, RTW_IDR0), 1126 1.132 msaitoh idr1 = RTW_READ(regs, RTW_IDR1); 1127 1.1 dyoung 1128 1.75 dyoung (*addr)[0] = __SHIFTOUT(idr0, __BITS(0, 7)); 1129 1.75 dyoung (*addr)[1] = __SHIFTOUT(idr0, __BITS(8, 15)); 1130 1.75 dyoung (*addr)[2] = __SHIFTOUT(idr0, __BITS(16, 23)); 1131 1.131 msaitoh (*addr)[3] = __SHIFTOUT(idr0, __BITS(24, 31)); 1132 1.1 dyoung 1133 1.75 dyoung (*addr)[4] = __SHIFTOUT(idr1, __BITS(0, 7)); 1134 1.75 dyoung (*addr)[5] = __SHIFTOUT(idr1, __BITS(8, 15)); 1135 1.1 dyoung 1136 1.1 dyoung if (IEEE80211_ADDR_EQ(addr, empty_macaddr)) { 1137 1.98 dyoung aprint_error_dev(dev, 1138 1.98 dyoung "could not get mac address, attach failed\n"); 1139 1.1 dyoung return ENXIO; 1140 1.1 dyoung } 1141 1.1 dyoung 1142 1.98 dyoung aprint_normal_dev(dev, "802.11 address %s\n", ether_sprintf(*addr)); 1143 1.1 dyoung 1144 1.1 dyoung return 0; 1145 1.1 dyoung } 1146 1.1 dyoung 1147 1.37 dyoung static uint8_t 1148 1.1 dyoung rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic, 1149 1.1 dyoung struct ieee80211_channel *chan) 1150 1.1 dyoung { 1151 1.1 dyoung u_int idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1; 1152 1.97 dyoung KASSERT(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14); 1153 1.1 dyoung return RTW_SR_GET(sr, idx); 1154 1.1 dyoung } 1155 1.1 dyoung 1156 1.1 dyoung static void 1157 1.34 dyoung rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *tdb) 1158 1.1 dyoung { 1159 1.1 dyoung int pri; 1160 1.58 dyoung /* nfree: the number of free descriptors in each ring. 1161 1.58 dyoung * The beacon ring is a special case: I do not let the 1162 1.58 dyoung * driver use all of the descriptors on the beacon ring. 1163 1.58 dyoung * The reasons are two-fold: 1164 1.58 dyoung * 1165 1.58 dyoung * (1) A BEACON descriptor's OWN bit is (apparently) not 1166 1.58 dyoung * updated, so the driver cannot easily know if the descriptor 1167 1.58 dyoung * belongs to it, or if it is racing the NIC. If the NIC 1168 1.58 dyoung * does not OWN every descriptor, then the driver can safely 1169 1.58 dyoung * update the descriptors when RTW_TBDA points at tdb_next. 1170 1.58 dyoung * 1171 1.58 dyoung * (2) I hope that the NIC will process more than one BEACON 1172 1.58 dyoung * descriptor in a single beacon interval, since that will 1173 1.58 dyoung * enable multiple-BSS support. Since the NIC does not 1174 1.58 dyoung * clear the OWN bit, there is no natural place for it to 1175 1.137 msaitoh * stop processing BEACON descriptors. Maybe it will *not* 1176 1.58 dyoung * stop processing them! I do not want to chance the NIC 1177 1.58 dyoung * looping around and around a saturated beacon ring, so 1178 1.58 dyoung * I will leave one descriptor unOWNed at all times. 1179 1.58 dyoung */ 1180 1.58 dyoung u_int nfree[RTW_NTXPRI] = 1181 1.58 dyoung {RTW_NTXDESCLO, RTW_NTXDESCMD, RTW_NTXDESCHI, 1182 1.58 dyoung RTW_NTXDESCBCN - 1}; 1183 1.1 dyoung 1184 1.1 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 1185 1.58 dyoung tdb[pri].tdb_nfree = nfree[pri]; 1186 1.34 dyoung tdb[pri].tdb_next = 0; 1187 1.1 dyoung } 1188 1.1 dyoung } 1189 1.1 dyoung 1190 1.1 dyoung static int 1191 1.34 dyoung rtw_txsoft_blk_init(struct rtw_txsoft_blk *tsb) 1192 1.1 dyoung { 1193 1.1 dyoung int i; 1194 1.34 dyoung struct rtw_txsoft *ts; 1195 1.1 dyoung 1196 1.34 dyoung SIMPLEQ_INIT(&tsb->tsb_dirtyq); 1197 1.34 dyoung SIMPLEQ_INIT(&tsb->tsb_freeq); 1198 1.34 dyoung for (i = 0; i < tsb->tsb_ndesc; i++) { 1199 1.34 dyoung ts = &tsb->tsb_desc[i]; 1200 1.34 dyoung ts->ts_mbuf = NULL; 1201 1.34 dyoung SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q); 1202 1.1 dyoung } 1203 1.58 dyoung tsb->tsb_tx_timer = 0; 1204 1.1 dyoung return 0; 1205 1.1 dyoung } 1206 1.1 dyoung 1207 1.1 dyoung static void 1208 1.34 dyoung rtw_txsoft_blk_init_all(struct rtw_txsoft_blk *tsb) 1209 1.1 dyoung { 1210 1.1 dyoung int pri; 1211 1.3 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) 1212 1.34 dyoung rtw_txsoft_blk_init(&tsb[pri]); 1213 1.1 dyoung } 1214 1.1 dyoung 1215 1.61 perry static inline void 1216 1.34 dyoung rtw_rxdescs_sync(struct rtw_rxdesc_blk *rdb, int desc0, int nsync, int ops) 1217 1.1 dyoung { 1218 1.34 dyoung KASSERT(nsync <= rdb->rdb_ndesc); 1219 1.1 dyoung /* sync to end of ring */ 1220 1.34 dyoung if (desc0 + nsync > rdb->rdb_ndesc) { 1221 1.34 dyoung bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap, 1222 1.1 dyoung offsetof(struct rtw_descs, hd_rx[desc0]), 1223 1.34 dyoung sizeof(struct rtw_rxdesc) * (rdb->rdb_ndesc - desc0), ops); 1224 1.34 dyoung nsync -= (rdb->rdb_ndesc - desc0); 1225 1.1 dyoung desc0 = 0; 1226 1.1 dyoung } 1227 1.1 dyoung 1228 1.34 dyoung KASSERT(desc0 < rdb->rdb_ndesc); 1229 1.34 dyoung KASSERT(nsync <= rdb->rdb_ndesc); 1230 1.34 dyoung KASSERT(desc0 + nsync <= rdb->rdb_ndesc); 1231 1.21 dyoung 1232 1.1 dyoung /* sync what remains */ 1233 1.34 dyoung bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap, 1234 1.1 dyoung offsetof(struct rtw_descs, hd_rx[desc0]), 1235 1.1 dyoung sizeof(struct rtw_rxdesc) * nsync, ops); 1236 1.1 dyoung } 1237 1.1 dyoung 1238 1.1 dyoung static void 1239 1.34 dyoung rtw_txdescs_sync(struct rtw_txdesc_blk *tdb, u_int desc0, u_int nsync, int ops) 1240 1.1 dyoung { 1241 1.1 dyoung /* sync to end of ring */ 1242 1.34 dyoung if (desc0 + nsync > tdb->tdb_ndesc) { 1243 1.34 dyoung bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap, 1244 1.34 dyoung tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0, 1245 1.34 dyoung sizeof(struct rtw_txdesc) * (tdb->tdb_ndesc - desc0), 1246 1.1 dyoung ops); 1247 1.34 dyoung nsync -= (tdb->tdb_ndesc - desc0); 1248 1.1 dyoung desc0 = 0; 1249 1.1 dyoung } 1250 1.1 dyoung 1251 1.1 dyoung /* sync what remains */ 1252 1.34 dyoung bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap, 1253 1.34 dyoung tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0, 1254 1.1 dyoung sizeof(struct rtw_txdesc) * nsync, ops); 1255 1.1 dyoung } 1256 1.1 dyoung 1257 1.1 dyoung static void 1258 1.34 dyoung rtw_txdescs_sync_all(struct rtw_txdesc_blk *tdb) 1259 1.1 dyoung { 1260 1.1 dyoung int pri; 1261 1.1 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 1262 1.34 dyoung rtw_txdescs_sync(&tdb[pri], 0, tdb[pri].tdb_ndesc, 1263 1.131 msaitoh BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1264 1.1 dyoung } 1265 1.1 dyoung } 1266 1.1 dyoung 1267 1.1 dyoung static void 1268 1.34 dyoung rtw_rxbufs_release(bus_dma_tag_t dmat, struct rtw_rxsoft *desc) 1269 1.1 dyoung { 1270 1.1 dyoung int i; 1271 1.34 dyoung struct rtw_rxsoft *rs; 1272 1.1 dyoung 1273 1.21 dyoung for (i = 0; i < RTW_RXQLEN; i++) { 1274 1.34 dyoung rs = &desc[i]; 1275 1.34 dyoung if (rs->rs_mbuf == NULL) 1276 1.31 dyoung continue; 1277 1.34 dyoung bus_dmamap_sync(dmat, rs->rs_dmamap, 0, 1278 1.34 dyoung rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); 1279 1.34 dyoung bus_dmamap_unload(dmat, rs->rs_dmamap); 1280 1.34 dyoung m_freem(rs->rs_mbuf); 1281 1.34 dyoung rs->rs_mbuf = NULL; 1282 1.1 dyoung } 1283 1.1 dyoung } 1284 1.1 dyoung 1285 1.61 perry static inline int 1286 1.34 dyoung rtw_rxsoft_alloc(bus_dma_tag_t dmat, struct rtw_rxsoft *rs) 1287 1.1 dyoung { 1288 1.1 dyoung int rc; 1289 1.1 dyoung struct mbuf *m; 1290 1.1 dyoung 1291 1.44 perry MGETHDR(m, M_DONTWAIT, MT_DATA); 1292 1.1 dyoung if (m == NULL) 1293 1.18 dyoung return ENOBUFS; 1294 1.1 dyoung 1295 1.44 perry MCLGET(m, M_DONTWAIT); 1296 1.31 dyoung if ((m->m_flags & M_EXT) == 0) { 1297 1.31 dyoung m_freem(m); 1298 1.18 dyoung return ENOBUFS; 1299 1.31 dyoung } 1300 1.1 dyoung 1301 1.1 dyoung m->m_pkthdr.len = m->m_len = m->m_ext.ext_size; 1302 1.1 dyoung 1303 1.34 dyoung if (rs->rs_mbuf != NULL) 1304 1.34 dyoung bus_dmamap_unload(dmat, rs->rs_dmamap); 1305 1.18 dyoung 1306 1.34 dyoung rs->rs_mbuf = NULL; 1307 1.18 dyoung 1308 1.34 dyoung rc = bus_dmamap_load_mbuf(dmat, rs->rs_dmamap, m, BUS_DMA_NOWAIT); 1309 1.18 dyoung if (rc != 0) { 1310 1.18 dyoung m_freem(m); 1311 1.18 dyoung return -1; 1312 1.18 dyoung } 1313 1.1 dyoung 1314 1.34 dyoung rs->rs_mbuf = m; 1315 1.1 dyoung 1316 1.1 dyoung return 0; 1317 1.1 dyoung } 1318 1.1 dyoung 1319 1.1 dyoung static int 1320 1.34 dyoung rtw_rxsoft_init_all(bus_dma_tag_t dmat, struct rtw_rxsoft *desc, 1321 1.98 dyoung int *ndesc, device_t dev) 1322 1.1 dyoung { 1323 1.31 dyoung int i, rc = 0; 1324 1.34 dyoung struct rtw_rxsoft *rs; 1325 1.1 dyoung 1326 1.21 dyoung for (i = 0; i < RTW_RXQLEN; i++) { 1327 1.34 dyoung rs = &desc[i]; 1328 1.31 dyoung /* we're in rtw_init, so there should be no mbufs allocated */ 1329 1.34 dyoung KASSERT(rs->rs_mbuf == NULL); 1330 1.31 dyoung #ifdef RTW_DEBUG 1331 1.31 dyoung if (i == rtw_rxbufs_limit) { 1332 1.98 dyoung aprint_error_dev(dev, "TEST hit %d-buffer limit\n", i); 1333 1.31 dyoung rc = ENOBUFS; 1334 1.31 dyoung break; 1335 1.31 dyoung } 1336 1.31 dyoung #endif /* RTW_DEBUG */ 1337 1.34 dyoung if ((rc = rtw_rxsoft_alloc(dmat, rs)) != 0) { 1338 1.98 dyoung aprint_error_dev(dev, 1339 1.98 dyoung "rtw_rxsoft_alloc failed, %d buffers, rc %d\n", 1340 1.98 dyoung i, rc); 1341 1.31 dyoung break; 1342 1.1 dyoung } 1343 1.1 dyoung } 1344 1.31 dyoung *ndesc = i; 1345 1.31 dyoung return rc; 1346 1.1 dyoung } 1347 1.1 dyoung 1348 1.61 perry static inline void 1349 1.34 dyoung rtw_rxdesc_init(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *rs, 1350 1.81 christos int idx, int kick) 1351 1.1 dyoung { 1352 1.34 dyoung int is_last = (idx == rdb->rdb_ndesc - 1); 1353 1.21 dyoung uint32_t ctl, octl, obuf; 1354 1.34 dyoung struct rtw_rxdesc *rd = &rdb->rdb_desc[idx]; 1355 1.1 dyoung 1356 1.92 dyoung /* sync the mbuf before the descriptor */ 1357 1.92 dyoung bus_dmamap_sync(rdb->rdb_dmat, rs->rs_dmamap, 0, 1358 1.92 dyoung rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); 1359 1.92 dyoung 1360 1.34 dyoung obuf = rd->rd_buf; 1361 1.34 dyoung rd->rd_buf = htole32(rs->rs_dmamap->dm_segs[0].ds_addr); 1362 1.1 dyoung 1363 1.75 dyoung ctl = __SHIFTIN(rs->rs_mbuf->m_len, RTW_RXCTL_LENGTH_MASK) | 1364 1.1 dyoung RTW_RXCTL_OWN | RTW_RXCTL_FS | RTW_RXCTL_LS; 1365 1.1 dyoung 1366 1.1 dyoung if (is_last) 1367 1.1 dyoung ctl |= RTW_RXCTL_EOR; 1368 1.1 dyoung 1369 1.34 dyoung octl = rd->rd_ctl; 1370 1.34 dyoung rd->rd_ctl = htole32(ctl); 1371 1.1 dyoung 1372 1.120 christos #ifdef RTW_DEBUG 1373 1.24 dyoung RTW_DPRINTF( 1374 1.24 dyoung kick ? (RTW_DEBUG_RECV_DESC | RTW_DEBUG_IO_KICK) 1375 1.132 msaitoh : RTW_DEBUG_RECV_DESC, 1376 1.34 dyoung ("%s: rd %p buf %08x -> %08x ctl %08x -> %08x\n", __func__, rd, 1377 1.34 dyoung le32toh(obuf), le32toh(rd->rd_buf), le32toh(octl), 1378 1.34 dyoung le32toh(rd->rd_ctl))); 1379 1.120 christos #else 1380 1.120 christos __USE(octl); 1381 1.120 christos __USE(obuf); 1382 1.120 christos #endif 1383 1.21 dyoung 1384 1.1 dyoung /* sync the descriptor */ 1385 1.34 dyoung bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap, 1386 1.33 dyoung RTW_DESC_OFFSET(hd_rx, idx), sizeof(struct rtw_rxdesc), 1387 1.131 msaitoh BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1388 1.1 dyoung } 1389 1.1 dyoung 1390 1.1 dyoung static void 1391 1.34 dyoung rtw_rxdesc_init_all(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *ctl, int kick) 1392 1.1 dyoung { 1393 1.1 dyoung int i; 1394 1.34 dyoung struct rtw_rxsoft *rs; 1395 1.1 dyoung 1396 1.34 dyoung for (i = 0; i < rdb->rdb_ndesc; i++) { 1397 1.34 dyoung rs = &ctl[i]; 1398 1.34 dyoung rtw_rxdesc_init(rdb, rs, i, kick); 1399 1.1 dyoung } 1400 1.1 dyoung } 1401 1.1 dyoung 1402 1.1 dyoung static void 1403 1.83 dyoung rtw_io_enable(struct rtw_softc *sc, uint8_t flags, int enable) 1404 1.1 dyoung { 1405 1.83 dyoung struct rtw_regs *regs = &sc->sc_regs; 1406 1.37 dyoung uint8_t cr; 1407 1.1 dyoung 1408 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_IOSTATE, ("%s: %s 0x%02x\n", __func__, 1409 1.1 dyoung enable ? "enable" : "disable", flags)); 1410 1.1 dyoung 1411 1.1 dyoung cr = RTW_READ8(regs, RTW_CR); 1412 1.1 dyoung 1413 1.1 dyoung /* XXX reference source does not enable MULRW */ 1414 1.1 dyoung /* enable PCI Read/Write Multiple */ 1415 1.1 dyoung cr |= RTW_CR_MULRW; 1416 1.83 dyoung 1417 1.83 dyoung /* The receive engine will always start at RDSAR. */ 1418 1.83 dyoung if (enable && (flags & ~cr & RTW_CR_RE)) { 1419 1.83 dyoung struct rtw_rxdesc_blk *rdb; 1420 1.83 dyoung rdb = &sc->sc_rxdesc_blk; 1421 1.83 dyoung rdb->rdb_next = 0; 1422 1.83 dyoung } 1423 1.1 dyoung 1424 1.1 dyoung RTW_RBW(regs, RTW_CR, RTW_CR); /* XXX paranoia? */ 1425 1.1 dyoung if (enable) 1426 1.1 dyoung cr |= flags; 1427 1.1 dyoung else 1428 1.1 dyoung cr &= ~flags; 1429 1.1 dyoung RTW_WRITE8(regs, RTW_CR, cr); 1430 1.1 dyoung RTW_SYNC(regs, RTW_CR, RTW_CR); 1431 1.83 dyoung 1432 1.83 dyoung #ifdef RTW_DIAG 1433 1.83 dyoung if (cr & RTW_CR_TE) 1434 1.83 dyoung rtw_txring_fixup(sc, __func__, __LINE__); 1435 1.83 dyoung #endif 1436 1.103 dyoung if (cr & RTW_CR_TE) { 1437 1.103 dyoung rtw_tx_kick(&sc->sc_regs, 1438 1.103 dyoung RTW_TPPOLL_HPQ | RTW_TPPOLL_NPQ | RTW_TPPOLL_LPQ); 1439 1.103 dyoung } 1440 1.1 dyoung } 1441 1.1 dyoung 1442 1.1 dyoung static void 1443 1.81 christos rtw_intr_rx(struct rtw_softc *sc, uint16_t isr) 1444 1.1 dyoung { 1445 1.42 dyoung #define IS_BEACON(__fc0) \ 1446 1.42 dyoung ((__fc0 & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==\ 1447 1.42 dyoung (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON)) 1448 1.42 dyoung 1449 1.30 dyoung static const int ratetbl[4] = {2, 4, 11, 22}; /* convert rates: 1450 1.30 dyoung * hardware -> net80211 1451 1.30 dyoung */ 1452 1.21 dyoung u_int next, nproc = 0; 1453 1.125 nonaka int hwrate, len, rate, rssi, sq, s; 1454 1.37 dyoung uint32_t hrssi, hstat, htsfth, htsftl; 1455 1.34 dyoung struct rtw_rxdesc *rd; 1456 1.34 dyoung struct rtw_rxsoft *rs; 1457 1.34 dyoung struct rtw_rxdesc_blk *rdb; 1458 1.1 dyoung struct mbuf *m; 1459 1.48 dyoung struct ifnet *ifp = &sc->sc_if; 1460 1.1 dyoung 1461 1.1 dyoung struct ieee80211_node *ni; 1462 1.48 dyoung struct ieee80211_frame_min *wh; 1463 1.1 dyoung 1464 1.34 dyoung rdb = &sc->sc_rxdesc_blk; 1465 1.21 dyoung 1466 1.83 dyoung for (next = rdb->rdb_next; ; next = rdb->rdb_next) { 1467 1.83 dyoung KASSERT(next < rdb->rdb_ndesc); 1468 1.93 dyoung 1469 1.34 dyoung rtw_rxdescs_sync(rdb, next, 1, 1470 1.131 msaitoh BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1471 1.34 dyoung rd = &rdb->rdb_desc[next]; 1472 1.34 dyoung rs = &sc->sc_rxsoft[next]; 1473 1.1 dyoung 1474 1.34 dyoung hstat = le32toh(rd->rd_stat); 1475 1.34 dyoung hrssi = le32toh(rd->rd_rssi); 1476 1.34 dyoung htsfth = le32toh(rd->rd_tsfth); 1477 1.34 dyoung htsftl = le32toh(rd->rd_tsftl); 1478 1.1 dyoung 1479 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_RECV_DESC, 1480 1.21 dyoung ("%s: rxdesc[%d] hstat %08x hrssi %08x htsft %08x%08x\n", 1481 1.21 dyoung __func__, next, hstat, hrssi, htsfth, htsftl)); 1482 1.21 dyoung 1483 1.21 dyoung ++nproc; 1484 1.21 dyoung 1485 1.21 dyoung /* still belongs to NIC */ 1486 1.21 dyoung if ((hstat & RTW_RXSTAT_OWN) != 0) { 1487 1.82 dyoung rtw_rxdescs_sync(rdb, next, 1, BUS_DMASYNC_PREREAD); 1488 1.83 dyoung break; 1489 1.83 dyoung } 1490 1.1 dyoung 1491 1.132 msaitoh /* ieee80211_input() might reset the receive engine 1492 1.132 msaitoh * (e.g. by indirectly calling rtw_tune()), so save 1493 1.132 msaitoh * the next pointer here and retrieve it again on 1494 1.132 msaitoh * the next round. 1495 1.83 dyoung */ 1496 1.83 dyoung rdb->rdb_next = (next + 1) % rdb->rdb_ndesc; 1497 1.1 dyoung 1498 1.45 dyoung #ifdef RTW_DEBUG 1499 1.45 dyoung #define PRINTSTAT(flag) do { \ 1500 1.45 dyoung if ((hstat & flag) != 0) { \ 1501 1.45 dyoung printf("%s" #flag, delim); \ 1502 1.45 dyoung delim = ","; \ 1503 1.45 dyoung } \ 1504 1.45 dyoung } while (0) 1505 1.45 dyoung if ((rtw_debug & RTW_DEBUG_RECV_DESC) != 0) { 1506 1.45 dyoung const char *delim = "<"; 1507 1.98 dyoung printf("%s: ", device_xname(sc->sc_dev)); 1508 1.45 dyoung if ((hstat & RTW_RXSTAT_DEBUG) != 0) { 1509 1.45 dyoung printf("status %08x", hstat); 1510 1.45 dyoung PRINTSTAT(RTW_RXSTAT_SPLCP); 1511 1.45 dyoung PRINTSTAT(RTW_RXSTAT_MAR); 1512 1.45 dyoung PRINTSTAT(RTW_RXSTAT_PAR); 1513 1.45 dyoung PRINTSTAT(RTW_RXSTAT_BAR); 1514 1.45 dyoung PRINTSTAT(RTW_RXSTAT_PWRMGT); 1515 1.45 dyoung PRINTSTAT(RTW_RXSTAT_CRC32); 1516 1.45 dyoung PRINTSTAT(RTW_RXSTAT_ICV); 1517 1.45 dyoung printf(">, "); 1518 1.45 dyoung } 1519 1.45 dyoung } 1520 1.45 dyoung #endif /* RTW_DEBUG */ 1521 1.45 dyoung 1522 1.1 dyoung if ((hstat & RTW_RXSTAT_IOERROR) != 0) { 1523 1.98 dyoung aprint_error_dev(sc->sc_dev, 1524 1.98 dyoung "DMA error/FIFO overflow %08" PRIx32 ", " 1525 1.98 dyoung "rx descriptor %d\n", hstat, next); 1526 1.135 thorpej if_statinc(ifp, if_ierrors); 1527 1.1 dyoung goto next; 1528 1.1 dyoung } 1529 1.1 dyoung 1530 1.75 dyoung len = __SHIFTOUT(hstat, RTW_RXSTAT_LENGTH_MASK); 1531 1.22 dyoung if (len < IEEE80211_MIN_LEN) { 1532 1.22 dyoung sc->sc_ic.ic_stats.is_rx_tooshort++; 1533 1.22 dyoung goto next; 1534 1.22 dyoung } 1535 1.98 dyoung if (len > rs->rs_mbuf->m_len) { 1536 1.101 dyoung aprint_error_dev(sc->sc_dev, 1537 1.101 dyoung "rx frame too long, %d > %d, %08" PRIx32 1538 1.101 dyoung ", desc %d\n", 1539 1.101 dyoung len, rs->rs_mbuf->m_len, hstat, next); 1540 1.135 thorpej if_statinc(ifp, if_ierrors); 1541 1.98 dyoung goto next; 1542 1.98 dyoung } 1543 1.43 thorpej 1544 1.75 dyoung hwrate = __SHIFTOUT(hstat, RTW_RXSTAT_RATE_MASK); 1545 1.87 dyoung if (hwrate >= __arraycount(ratetbl)) { 1546 1.98 dyoung aprint_error_dev(sc->sc_dev, 1547 1.98 dyoung "unknown rate #%" __PRIuBITS "\n", 1548 1.75 dyoung __SHIFTOUT(hstat, RTW_RXSTAT_RATE_MASK)); 1549 1.135 thorpej if_statinc(ifp, if_ierrors); 1550 1.22 dyoung goto next; 1551 1.1 dyoung } 1552 1.30 dyoung rate = ratetbl[hwrate]; 1553 1.1 dyoung 1554 1.1 dyoung #ifdef RTW_DEBUG 1555 1.45 dyoung RTW_DPRINTF(RTW_DEBUG_RECV_DESC, 1556 1.45 dyoung ("rate %d.%d Mb/s, time %08x%08x\n", (rate * 5) / 10, 1557 1.45 dyoung (rate * 5) % 10, htsfth, htsftl)); 1558 1.1 dyoung #endif /* RTW_DEBUG */ 1559 1.1 dyoung 1560 1.1 dyoung /* if bad flags, skip descriptor */ 1561 1.1 dyoung if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) { 1562 1.98 dyoung aprint_error_dev(sc->sc_dev, "too many rx segments, " 1563 1.98 dyoung "next=%d, %08" PRIx32 "\n", next, hstat); 1564 1.1 dyoung goto next; 1565 1.1 dyoung } 1566 1.1 dyoung 1567 1.34 dyoung bus_dmamap_sync(sc->sc_dmat, rs->rs_dmamap, 0, 1568 1.34 dyoung rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); 1569 1.18 dyoung 1570 1.34 dyoung m = rs->rs_mbuf; 1571 1.1 dyoung 1572 1.1 dyoung /* if temporarily out of memory, re-use mbuf */ 1573 1.34 dyoung switch (rtw_rxsoft_alloc(sc->sc_dmat, rs)) { 1574 1.18 dyoung case 0: 1575 1.18 dyoung break; 1576 1.18 dyoung case ENOBUFS: 1577 1.98 dyoung aprint_error_dev(sc->sc_dev, 1578 1.98 dyoung "rtw_rxsoft_alloc(, %d) failed, dropping packet\n", 1579 1.98 dyoung next); 1580 1.1 dyoung goto next; 1581 1.18 dyoung default: 1582 1.18 dyoung /* XXX shorten rx ring, instead? */ 1583 1.98 dyoung aprint_error_dev(sc->sc_dev, 1584 1.98 dyoung "could not load DMA map\n"); 1585 1.1 dyoung } 1586 1.1 dyoung 1587 1.93 dyoung sq = __SHIFTOUT(hrssi, RTW_RXRSSI_SQ); 1588 1.93 dyoung 1589 1.1 dyoung if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS) 1590 1.93 dyoung rssi = UINT8_MAX - sq; 1591 1.1 dyoung else { 1592 1.75 dyoung rssi = __SHIFTOUT(hrssi, RTW_RXRSSI_IMR_RSSI); 1593 1.1 dyoung /* TBD find out each front-end's LNA gain in the 1594 1.1 dyoung * front-end's units 1595 1.1 dyoung */ 1596 1.1 dyoung if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0) 1597 1.1 dyoung rssi |= 0x80; 1598 1.1 dyoung } 1599 1.1 dyoung 1600 1.34 dyoung /* Note well: now we cannot recycle the rs_mbuf unless 1601 1.32 dyoung * we restore its original length. 1602 1.32 dyoung */ 1603 1.123 ozaki m_set_rcvif(m, ifp); 1604 1.22 dyoung m->m_pkthdr.len = m->m_len = len; 1605 1.1 dyoung 1606 1.48 dyoung wh = mtod(m, struct ieee80211_frame_min *); 1607 1.42 dyoung 1608 1.125 nonaka s = splnet(); 1609 1.125 nonaka 1610 1.42 dyoung if (!IS_BEACON(wh->i_fc[0])) 1611 1.42 dyoung sc->sc_led_state.ls_event |= RTW_LED_S_RX; 1612 1.1 dyoung 1613 1.1 dyoung sc->sc_tsfth = htsfth; 1614 1.1 dyoung 1615 1.10 dyoung #ifdef RTW_DEBUG 1616 1.131 msaitoh if ((ifp->if_flags & (IFF_DEBUG | IFF_LINK2)) == 1617 1.131 msaitoh (IFF_DEBUG | IFF_LINK2)) { 1618 1.10 dyoung ieee80211_dump_pkt(mtod(m, uint8_t *), m->m_pkthdr.len, 1619 1.10 dyoung rate, rssi); 1620 1.10 dyoung } 1621 1.10 dyoung #endif /* RTW_DEBUG */ 1622 1.32 dyoung 1623 1.32 dyoung if (sc->sc_radiobpf != NULL) { 1624 1.32 dyoung struct rtw_rx_radiotap_header *rr = &sc->sc_rxtap; 1625 1.32 dyoung 1626 1.32 dyoung rr->rr_tsft = 1627 1.32 dyoung htole64(((uint64_t)htsfth << 32) | htsftl); 1628 1.32 dyoung 1629 1.93 dyoung rr->rr_flags = IEEE80211_RADIOTAP_F_FCS; 1630 1.93 dyoung 1631 1.32 dyoung if ((hstat & RTW_RXSTAT_SPLCP) != 0) 1632 1.93 dyoung rr->rr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 1633 1.93 dyoung if ((hstat & RTW_RXSTAT_CRC32) != 0) 1634 1.93 dyoung rr->rr_flags |= IEEE80211_RADIOTAP_F_BADFCS; 1635 1.32 dyoung 1636 1.32 dyoung rr->rr_rate = rate; 1637 1.32 dyoung 1638 1.93 dyoung if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS) 1639 1.93 dyoung rr->rr_u.u_philips.p_antsignal = rssi; 1640 1.93 dyoung else { 1641 1.93 dyoung rr->rr_u.u_other.o_antsignal = rssi; 1642 1.93 dyoung rr->rr_u.u_other.o_barker_lock = 1643 1.93 dyoung htole16(UINT8_MAX - sq); 1644 1.93 dyoung } 1645 1.93 dyoung 1646 1.116 joerg bpf_mtap2(sc->sc_radiobpf, 1647 1.128 msaitoh rr, sizeof(sc->sc_rxtapu), m, BPF_D_IN); 1648 1.32 dyoung } 1649 1.32 dyoung 1650 1.93 dyoung if ((hstat & RTW_RXSTAT_RES) != 0) { 1651 1.93 dyoung m_freem(m); 1652 1.125 nonaka splx(s); 1653 1.93 dyoung goto next; 1654 1.93 dyoung } 1655 1.93 dyoung 1656 1.93 dyoung /* CRC is included with the packet; trim it off. */ 1657 1.93 dyoung m_adj(m, -IEEE80211_CRC_LEN); 1658 1.93 dyoung 1659 1.93 dyoung /* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */ 1660 1.93 dyoung ni = ieee80211_find_rxnode(&sc->sc_ic, wh); 1661 1.48 dyoung ieee80211_input(&sc->sc_ic, m, ni, rssi, htsftl); 1662 1.48 dyoung ieee80211_free_node(ni); 1663 1.125 nonaka splx(s); 1664 1.1 dyoung next: 1665 1.34 dyoung rtw_rxdesc_init(rdb, rs, next, 0); 1666 1.1 dyoung } 1667 1.42 dyoung #undef IS_BEACON 1668 1.1 dyoung } 1669 1.1 dyoung 1670 1.1 dyoung static void 1671 1.81 christos rtw_txsoft_release(bus_dma_tag_t dmat, struct ieee80211com *ic, 1672 1.34 dyoung struct rtw_txsoft *ts) 1673 1.5 dyoung { 1674 1.5 dyoung struct mbuf *m; 1675 1.5 dyoung struct ieee80211_node *ni; 1676 1.5 dyoung 1677 1.34 dyoung m = ts->ts_mbuf; 1678 1.34 dyoung ni = ts->ts_ni; 1679 1.21 dyoung KASSERT(m != NULL); 1680 1.21 dyoung KASSERT(ni != NULL); 1681 1.34 dyoung ts->ts_mbuf = NULL; 1682 1.34 dyoung ts->ts_ni = NULL; 1683 1.5 dyoung 1684 1.34 dyoung bus_dmamap_sync(dmat, ts->ts_dmamap, 0, ts->ts_dmamap->dm_mapsize, 1685 1.5 dyoung BUS_DMASYNC_POSTWRITE); 1686 1.34 dyoung bus_dmamap_unload(dmat, ts->ts_dmamap); 1687 1.5 dyoung m_freem(m); 1688 1.48 dyoung ieee80211_free_node(ni); 1689 1.5 dyoung } 1690 1.5 dyoung 1691 1.5 dyoung static void 1692 1.34 dyoung rtw_txsofts_release(bus_dma_tag_t dmat, struct ieee80211com *ic, 1693 1.34 dyoung struct rtw_txsoft_blk *tsb) 1694 1.5 dyoung { 1695 1.34 dyoung struct rtw_txsoft *ts; 1696 1.5 dyoung 1697 1.34 dyoung while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) { 1698 1.34 dyoung rtw_txsoft_release(dmat, ic, ts); 1699 1.34 dyoung SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q); 1700 1.34 dyoung SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q); 1701 1.5 dyoung } 1702 1.58 dyoung tsb->tsb_tx_timer = 0; 1703 1.5 dyoung } 1704 1.5 dyoung 1705 1.61 perry static inline void 1706 1.34 dyoung rtw_collect_txpkt(struct rtw_softc *sc, struct rtw_txdesc_blk *tdb, 1707 1.34 dyoung struct rtw_txsoft *ts, int ndesc) 1708 1.5 dyoung { 1709 1.11 dyoung uint32_t hstat; 1710 1.5 dyoung int data_retry, rts_retry; 1711 1.34 dyoung struct rtw_txdesc *tdn; 1712 1.5 dyoung const char *condstring; 1713 1.48 dyoung struct ifnet *ifp = &sc->sc_if; 1714 1.5 dyoung 1715 1.34 dyoung rtw_txsoft_release(sc->sc_dmat, &sc->sc_ic, ts); 1716 1.5 dyoung 1717 1.34 dyoung tdb->tdb_nfree += ndesc; 1718 1.5 dyoung 1719 1.34 dyoung tdn = &tdb->tdb_desc[ts->ts_last]; 1720 1.5 dyoung 1721 1.34 dyoung hstat = le32toh(tdn->td_stat); 1722 1.75 dyoung rts_retry = __SHIFTOUT(hstat, RTW_TXSTAT_RTSRETRY_MASK); 1723 1.75 dyoung data_retry = __SHIFTOUT(hstat, RTW_TXSTAT_DRC_MASK); 1724 1.5 dyoung 1725 1.135 thorpej if (rts_retry + data_retry) 1726 1.135 thorpej if_statadd(ifp, if_collisions, rts_retry + data_retry); 1727 1.5 dyoung 1728 1.11 dyoung if ((hstat & RTW_TXSTAT_TOK) != 0) 1729 1.5 dyoung condstring = "ok"; 1730 1.5 dyoung else { 1731 1.135 thorpej if_statinc(ifp, if_oerrors); 1732 1.5 dyoung condstring = "error"; 1733 1.5 dyoung } 1734 1.5 dyoung 1735 1.120 christos #ifdef RTW_DEBUG 1736 1.21 dyoung DPRINTF(sc, RTW_DEBUG_XMIT_DESC, 1737 1.34 dyoung ("%s: ts %p txdesc[%d, %d] %s tries rts %u data %u\n", 1738 1.98 dyoung device_xname(sc->sc_dev), ts, ts->ts_first, ts->ts_last, 1739 1.5 dyoung condstring, rts_retry, data_retry)); 1740 1.120 christos #else 1741 1.120 christos __USE(condstring); 1742 1.120 christos #endif 1743 1.5 dyoung } 1744 1.5 dyoung 1745 1.58 dyoung static void 1746 1.58 dyoung rtw_reset_oactive(struct rtw_softc *sc) 1747 1.58 dyoung { 1748 1.58 dyoung short oflags; 1749 1.58 dyoung int pri; 1750 1.58 dyoung struct rtw_txsoft_blk *tsb; 1751 1.58 dyoung struct rtw_txdesc_blk *tdb; 1752 1.58 dyoung oflags = sc->sc_if.if_flags; 1753 1.58 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 1754 1.58 dyoung tsb = &sc->sc_txsoft_blk[pri]; 1755 1.58 dyoung tdb = &sc->sc_txdesc_blk[pri]; 1756 1.58 dyoung if (!SIMPLEQ_EMPTY(&tsb->tsb_freeq) && tdb->tdb_nfree > 0) 1757 1.58 dyoung sc->sc_if.if_flags &= ~IFF_OACTIVE; 1758 1.58 dyoung } 1759 1.58 dyoung if (oflags != sc->sc_if.if_flags) { 1760 1.58 dyoung DPRINTF(sc, RTW_DEBUG_OACTIVE, 1761 1.58 dyoung ("%s: reset OACTIVE\n", __func__)); 1762 1.58 dyoung } 1763 1.58 dyoung } 1764 1.58 dyoung 1765 1.5 dyoung /* Collect transmitted packets. */ 1766 1.107 dyoung static bool 1767 1.34 dyoung rtw_collect_txring(struct rtw_softc *sc, struct rtw_txsoft_blk *tsb, 1768 1.58 dyoung struct rtw_txdesc_blk *tdb, int force) 1769 1.5 dyoung { 1770 1.107 dyoung bool collected = false; 1771 1.5 dyoung int ndesc; 1772 1.34 dyoung struct rtw_txsoft *ts; 1773 1.5 dyoung 1774 1.83 dyoung #ifdef RTW_DEBUG 1775 1.83 dyoung rtw_dump_rings(sc); 1776 1.83 dyoung #endif 1777 1.83 dyoung 1778 1.34 dyoung while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) { 1779 1.83 dyoung /* If we're clearing a failed transmission, only clear 1780 1.83 dyoung up to the last packet the hardware has processed. */ 1781 1.83 dyoung if (ts->ts_first == rtw_txring_next(&sc->sc_regs, tdb)) 1782 1.83 dyoung break; 1783 1.83 dyoung 1784 1.34 dyoung ndesc = 1 + ts->ts_last - ts->ts_first; 1785 1.34 dyoung if (ts->ts_last < ts->ts_first) 1786 1.34 dyoung ndesc += tdb->tdb_ndesc; 1787 1.5 dyoung 1788 1.6 dyoung KASSERT(ndesc > 0); 1789 1.6 dyoung 1790 1.34 dyoung rtw_txdescs_sync(tdb, ts->ts_first, ndesc, 1791 1.131 msaitoh BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1792 1.5 dyoung 1793 1.58 dyoung if (force) { 1794 1.83 dyoung int next; 1795 1.83 dyoung #ifdef RTW_DIAG 1796 1.83 dyoung printf("%s: clearing packet, stats", __func__); 1797 1.83 dyoung #endif 1798 1.83 dyoung for (next = ts->ts_first; ; 1799 1.83 dyoung next = RTW_NEXT_IDX(tdb, next)) { 1800 1.83 dyoung #ifdef RTW_DIAG 1801 1.83 dyoung printf(" %" PRIx32 "/%" PRIx32 "/%" PRIx32 "/%" PRIu32 "/%" PRIx32, le32toh(tdb->tdb_desc[next].td_stat), le32toh(tdb->tdb_desc[next].td_ctl1), le32toh(tdb->tdb_desc[next].td_buf), le32toh(tdb->tdb_desc[next].td_len), le32toh(tdb->tdb_desc[next].td_next)); 1802 1.83 dyoung #endif 1803 1.83 dyoung tdb->tdb_desc[next].td_stat &= 1804 1.58 dyoung ~htole32(RTW_TXSTAT_OWN); 1805 1.83 dyoung if (next == ts->ts_last) 1806 1.58 dyoung break; 1807 1.58 dyoung } 1808 1.58 dyoung rtw_txdescs_sync(tdb, ts->ts_first, ndesc, 1809 1.131 msaitoh BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1810 1.83 dyoung #ifdef RTW_DIAG 1811 1.83 dyoung next = RTW_NEXT_IDX(tdb, next); 1812 1.83 dyoung printf(" -> end %u stat %" PRIx32 ", was %u\n", next, 1813 1.83 dyoung le32toh(tdb->tdb_desc[next].td_stat), 1814 1.83 dyoung rtw_txring_next(&sc->sc_regs, tdb)); 1815 1.83 dyoung #endif 1816 1.58 dyoung } else if ((tdb->tdb_desc[ts->ts_last].td_stat & 1817 1.82 dyoung htole32(RTW_TXSTAT_OWN)) != 0) { 1818 1.82 dyoung rtw_txdescs_sync(tdb, ts->ts_last, 1, 1819 1.82 dyoung BUS_DMASYNC_PREREAD); 1820 1.5 dyoung break; 1821 1.82 dyoung } 1822 1.5 dyoung 1823 1.107 dyoung collected = true; 1824 1.107 dyoung 1825 1.34 dyoung rtw_collect_txpkt(sc, tdb, ts, ndesc); 1826 1.34 dyoung SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q); 1827 1.34 dyoung SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q); 1828 1.5 dyoung } 1829 1.83 dyoung 1830 1.74 blymn /* no more pending transmissions, cancel watchdog */ 1831 1.34 dyoung if (ts == NULL) 1832 1.34 dyoung tsb->tsb_tx_timer = 0; 1833 1.58 dyoung rtw_reset_oactive(sc); 1834 1.107 dyoung 1835 1.107 dyoung return collected; 1836 1.5 dyoung } 1837 1.5 dyoung 1838 1.5 dyoung static void 1839 1.37 dyoung rtw_intr_tx(struct rtw_softc *sc, uint16_t isr) 1840 1.1 dyoung { 1841 1.125 nonaka int pri, s; 1842 1.34 dyoung struct rtw_txsoft_blk *tsb; 1843 1.34 dyoung struct rtw_txdesc_blk *tdb; 1844 1.48 dyoung struct ifnet *ifp = &sc->sc_if; 1845 1.5 dyoung 1846 1.125 nonaka s = splnet(); 1847 1.125 nonaka 1848 1.5 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 1849 1.34 dyoung tsb = &sc->sc_txsoft_blk[pri]; 1850 1.34 dyoung tdb = &sc->sc_txdesc_blk[pri]; 1851 1.58 dyoung rtw_collect_txring(sc, tsb, tdb, 0); 1852 1.58 dyoung } 1853 1.5 dyoung 1854 1.58 dyoung if ((isr & RTW_INTR_TX) != 0) 1855 1.126 ozaki rtw_start(ifp); /* in softint */ 1856 1.5 dyoung 1857 1.125 nonaka splx(s); 1858 1.1 dyoung } 1859 1.1 dyoung 1860 1.1 dyoung static void 1861 1.37 dyoung rtw_intr_beacon(struct rtw_softc *sc, uint16_t isr) 1862 1.1 dyoung { 1863 1.58 dyoung u_int next; 1864 1.58 dyoung uint32_t tsfth, tsftl; 1865 1.58 dyoung struct ieee80211com *ic; 1866 1.58 dyoung struct rtw_txdesc_blk *tdb = &sc->sc_txdesc_blk[RTW_TXPRIBCN]; 1867 1.58 dyoung struct rtw_txsoft_blk *tsb = &sc->sc_txsoft_blk[RTW_TXPRIBCN]; 1868 1.58 dyoung struct mbuf *m; 1869 1.125 nonaka int s; 1870 1.125 nonaka 1871 1.125 nonaka s = splnet(); 1872 1.58 dyoung 1873 1.58 dyoung tsfth = RTW_READ(&sc->sc_regs, RTW_TSFTRH); 1874 1.58 dyoung tsftl = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 1875 1.58 dyoung 1876 1.131 msaitoh if ((isr & (RTW_INTR_TBDOK | RTW_INTR_TBDER)) != 0) { 1877 1.58 dyoung next = rtw_txring_next(&sc->sc_regs, tdb); 1878 1.120 christos #ifdef RTW_DEBUG 1879 1.58 dyoung RTW_DPRINTF(RTW_DEBUG_BEACON, 1880 1.58 dyoung ("%s: beacon ring %sprocessed, isr = %#04" PRIx16 1881 1.58 dyoung ", next %u expected %u, %" PRIu64 "\n", __func__, 1882 1.58 dyoung (next == tdb->tdb_next) ? "" : "un", isr, next, 1883 1.58 dyoung tdb->tdb_next, (uint64_t)tsfth << 32 | tsftl)); 1884 1.120 christos #else 1885 1.120 christos __USE(next); 1886 1.120 christos __USE(tsfth); 1887 1.120 christos __USE(tsftl); 1888 1.120 christos #endif 1889 1.83 dyoung if ((RTW_READ8(&sc->sc_regs, RTW_TPPOLL) & RTW_TPPOLL_BQ) == 0) 1890 1.58 dyoung rtw_collect_txring(sc, tsb, tdb, 1); 1891 1.58 dyoung } 1892 1.58 dyoung /* Start beacon transmission. */ 1893 1.58 dyoung 1894 1.58 dyoung if ((isr & RTW_INTR_BCNINT) != 0 && 1895 1.58 dyoung sc->sc_ic.ic_state == IEEE80211_S_RUN && 1896 1.58 dyoung SIMPLEQ_EMPTY(&tsb->tsb_dirtyq)) { 1897 1.58 dyoung RTW_DPRINTF(RTW_DEBUG_BEACON, 1898 1.58 dyoung ("%s: beacon prep. time, isr = %#04" PRIx16 1899 1.58 dyoung ", %16" PRIu64 "\n", __func__, isr, 1900 1.58 dyoung (uint64_t)tsfth << 32 | tsftl)); 1901 1.58 dyoung ic = &sc->sc_ic; 1902 1.58 dyoung m = rtw_beacon_alloc(sc, ic->ic_bss); 1903 1.58 dyoung 1904 1.58 dyoung if (m == NULL) { 1905 1.98 dyoung aprint_error_dev(sc->sc_dev, 1906 1.98 dyoung "could not allocate beacon\n"); 1907 1.125 nonaka splx(s); 1908 1.58 dyoung return; 1909 1.58 dyoung } 1910 1.122 ozaki M_SETCTX(m, ieee80211_ref_node(ic->ic_bss)); 1911 1.58 dyoung IF_ENQUEUE(&sc->sc_beaconq, m); 1912 1.126 ozaki rtw_start(&sc->sc_if); /* in softint */ 1913 1.58 dyoung } 1914 1.125 nonaka 1915 1.125 nonaka splx(s); 1916 1.1 dyoung } 1917 1.1 dyoung 1918 1.1 dyoung static void 1919 1.81 christos rtw_intr_atim(struct rtw_softc *sc) 1920 1.1 dyoung { 1921 1.1 dyoung /* TBD */ 1922 1.1 dyoung return; 1923 1.1 dyoung } 1924 1.1 dyoung 1925 1.21 dyoung #ifdef RTW_DEBUG 1926 1.21 dyoung static void 1927 1.21 dyoung rtw_dump_rings(struct rtw_softc *sc) 1928 1.21 dyoung { 1929 1.34 dyoung struct rtw_txdesc_blk *tdb; 1930 1.34 dyoung struct rtw_rxdesc *rd; 1931 1.34 dyoung struct rtw_rxdesc_blk *rdb; 1932 1.21 dyoung int desc, pri; 1933 1.21 dyoung 1934 1.21 dyoung if ((rtw_debug & RTW_DEBUG_IO_KICK) == 0) 1935 1.21 dyoung return; 1936 1.21 dyoung 1937 1.21 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 1938 1.34 dyoung tdb = &sc->sc_txdesc_blk[pri]; 1939 1.21 dyoung printf("%s: txpri %d ndesc %d nfree %d\n", __func__, pri, 1940 1.34 dyoung tdb->tdb_ndesc, tdb->tdb_nfree); 1941 1.34 dyoung for (desc = 0; desc < tdb->tdb_ndesc; desc++) 1942 1.34 dyoung rtw_print_txdesc(sc, ".", NULL, tdb, desc); 1943 1.21 dyoung } 1944 1.21 dyoung 1945 1.34 dyoung rdb = &sc->sc_rxdesc_blk; 1946 1.33 dyoung 1947 1.21 dyoung for (desc = 0; desc < RTW_RXQLEN; desc++) { 1948 1.34 dyoung rd = &rdb->rdb_desc[desc]; 1949 1.31 dyoung printf("%s: %sctl %08x rsvd0/rssi %08x buf/tsftl %08x " 1950 1.21 dyoung "rsvd1/tsfth %08x\n", __func__, 1951 1.34 dyoung (desc >= rdb->rdb_ndesc) ? "UNUSED " : "", 1952 1.34 dyoung le32toh(rd->rd_ctl), le32toh(rd->rd_rssi), 1953 1.34 dyoung le32toh(rd->rd_buf), le32toh(rd->rd_tsfth)); 1954 1.21 dyoung } 1955 1.21 dyoung } 1956 1.21 dyoung #endif /* RTW_DEBUG */ 1957 1.21 dyoung 1958 1.1 dyoung static void 1959 1.3 dyoung rtw_hwring_setup(struct rtw_softc *sc) 1960 1.3 dyoung { 1961 1.58 dyoung int pri; 1962 1.3 dyoung struct rtw_regs *regs = &sc->sc_regs; 1963 1.58 dyoung struct rtw_txdesc_blk *tdb; 1964 1.58 dyoung 1965 1.58 dyoung sc->sc_txdesc_blk[RTW_TXPRILO].tdb_basereg = RTW_TLPDA; 1966 1.58 dyoung sc->sc_txdesc_blk[RTW_TXPRILO].tdb_base = RTW_RING_BASE(sc, hd_txlo); 1967 1.58 dyoung sc->sc_txdesc_blk[RTW_TXPRIMD].tdb_basereg = RTW_TNPDA; 1968 1.58 dyoung sc->sc_txdesc_blk[RTW_TXPRIMD].tdb_base = RTW_RING_BASE(sc, hd_txmd); 1969 1.58 dyoung sc->sc_txdesc_blk[RTW_TXPRIHI].tdb_basereg = RTW_THPDA; 1970 1.58 dyoung sc->sc_txdesc_blk[RTW_TXPRIHI].tdb_base = RTW_RING_BASE(sc, hd_txhi); 1971 1.58 dyoung sc->sc_txdesc_blk[RTW_TXPRIBCN].tdb_basereg = RTW_TBDA; 1972 1.58 dyoung sc->sc_txdesc_blk[RTW_TXPRIBCN].tdb_base = RTW_RING_BASE(sc, hd_bcn); 1973 1.58 dyoung 1974 1.58 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 1975 1.58 dyoung tdb = &sc->sc_txdesc_blk[pri]; 1976 1.58 dyoung RTW_WRITE(regs, tdb->tdb_basereg, tdb->tdb_base); 1977 1.58 dyoung RTW_DPRINTF(RTW_DEBUG_XMIT_DESC, 1978 1.58 dyoung ("%s: reg[tdb->tdb_basereg] <- %" PRIxPTR "\n", __func__, 1979 1.58 dyoung (uintptr_t)tdb->tdb_base)); 1980 1.58 dyoung } 1981 1.58 dyoung 1982 1.3 dyoung RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(sc, hd_rx)); 1983 1.58 dyoung 1984 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_RECV_DESC, 1985 1.21 dyoung ("%s: reg[RDSAR] <- %" PRIxPTR "\n", __func__, 1986 1.21 dyoung (uintptr_t)RTW_RING_BASE(sc, hd_rx))); 1987 1.58 dyoung 1988 1.58 dyoung RTW_SYNC(regs, RTW_TLPDA, RTW_RDSAR); 1989 1.58 dyoung 1990 1.3 dyoung } 1991 1.3 dyoung 1992 1.31 dyoung static int 1993 1.3 dyoung rtw_swring_setup(struct rtw_softc *sc) 1994 1.3 dyoung { 1995 1.31 dyoung int rc; 1996 1.34 dyoung struct rtw_rxdesc_blk *rdb; 1997 1.33 dyoung 1998 1.3 dyoung rtw_txdesc_blk_init_all(&sc->sc_txdesc_blk[0]); 1999 1.3 dyoung 2000 1.34 dyoung rtw_txsoft_blk_init_all(&sc->sc_txsoft_blk[0]); 2001 1.3 dyoung 2002 1.34 dyoung rdb = &sc->sc_rxdesc_blk; 2003 1.34 dyoung if ((rc = rtw_rxsoft_init_all(sc->sc_dmat, sc->sc_rxsoft, &rdb->rdb_ndesc, 2004 1.98 dyoung sc->sc_dev)) != 0 && rdb->rdb_ndesc == 0) { 2005 1.98 dyoung aprint_error_dev(sc->sc_dev, "could not allocate rx buffers\n"); 2006 1.31 dyoung return rc; 2007 1.31 dyoung } 2008 1.44 perry 2009 1.34 dyoung rdb = &sc->sc_rxdesc_blk; 2010 1.34 dyoung rtw_rxdescs_sync(rdb, 0, rdb->rdb_ndesc, 2011 1.131 msaitoh BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 2012 1.34 dyoung rtw_rxdesc_init_all(rdb, sc->sc_rxsoft, 1); 2013 1.58 dyoung rdb->rdb_next = 0; 2014 1.3 dyoung 2015 1.33 dyoung rtw_txdescs_sync_all(&sc->sc_txdesc_blk[0]); 2016 1.31 dyoung return 0; 2017 1.3 dyoung } 2018 1.3 dyoung 2019 1.3 dyoung static void 2020 1.58 dyoung rtw_txdesc_blk_init(struct rtw_txdesc_blk *tdb) 2021 1.21 dyoung { 2022 1.21 dyoung int i; 2023 1.21 dyoung 2024 1.34 dyoung (void)memset(tdb->tdb_desc, 0, 2025 1.34 dyoung sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc); 2026 1.34 dyoung for (i = 0; i < tdb->tdb_ndesc; i++) 2027 1.34 dyoung tdb->tdb_desc[i].td_next = htole32(RTW_NEXT_DESC(tdb, i)); 2028 1.58 dyoung } 2029 1.58 dyoung 2030 1.58 dyoung static u_int 2031 1.58 dyoung rtw_txring_next(struct rtw_regs *regs, struct rtw_txdesc_blk *tdb) 2032 1.58 dyoung { 2033 1.58 dyoung return (le32toh(RTW_READ(regs, tdb->tdb_basereg)) - tdb->tdb_base) / 2034 1.58 dyoung sizeof(struct rtw_txdesc); 2035 1.21 dyoung } 2036 1.21 dyoung 2037 1.83 dyoung #ifdef RTW_DIAG 2038 1.21 dyoung static void 2039 1.83 dyoung rtw_txring_fixup(struct rtw_softc *sc, const char *fn, int ln) 2040 1.3 dyoung { 2041 1.5 dyoung int pri; 2042 1.58 dyoung u_int next; 2043 1.34 dyoung struct rtw_txdesc_blk *tdb; 2044 1.58 dyoung struct rtw_regs *regs = &sc->sc_regs; 2045 1.21 dyoung 2046 1.21 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 2047 1.83 dyoung int i; 2048 1.34 dyoung tdb = &sc->sc_txdesc_blk[pri]; 2049 1.58 dyoung next = rtw_txring_next(regs, tdb); 2050 1.58 dyoung if (tdb->tdb_next == next) 2051 1.58 dyoung continue; 2052 1.83 dyoung for (i = 0; next != tdb->tdb_next; 2053 1.83 dyoung next = RTW_NEXT_IDX(tdb, next), i++) { 2054 1.83 dyoung if ((tdb->tdb_desc[next].td_stat & htole32(RTW_TXSTAT_OWN)) == 0) 2055 1.83 dyoung break; 2056 1.83 dyoung } 2057 1.83 dyoung printf("%s:%d: tx-ring %d expected next %u, read %u+%d -> %s\n", fn, 2058 1.83 dyoung ln, pri, tdb->tdb_next, next, i, tdb->tdb_next == next ? "okay" : "BAD"); 2059 1.83 dyoung if (tdb->tdb_next == next) 2060 1.83 dyoung continue; 2061 1.65 dyoung tdb->tdb_next = MIN(next, tdb->tdb_ndesc - 1); 2062 1.58 dyoung } 2063 1.58 dyoung } 2064 1.83 dyoung #endif 2065 1.21 dyoung 2066 1.21 dyoung static void 2067 1.58 dyoung rtw_txdescs_reset(struct rtw_softc *sc) 2068 1.21 dyoung { 2069 1.58 dyoung int pri; 2070 1.83 dyoung struct rtw_txsoft_blk *tsb; 2071 1.83 dyoung struct rtw_txdesc_blk *tdb; 2072 1.58 dyoung 2073 1.58 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 2074 1.83 dyoung tsb = &sc->sc_txsoft_blk[pri]; 2075 1.83 dyoung tdb = &sc->sc_txdesc_blk[pri]; 2076 1.83 dyoung rtw_collect_txring(sc, tsb, tdb, 1); 2077 1.83 dyoung #ifdef RTW_DIAG 2078 1.83 dyoung if (!SIMPLEQ_EMPTY(&tsb->tsb_dirtyq)) 2079 1.83 dyoung printf("%s: packets left in ring %d\n", __func__, pri); 2080 1.83 dyoung #endif 2081 1.58 dyoung } 2082 1.21 dyoung } 2083 1.21 dyoung 2084 1.21 dyoung static void 2085 1.21 dyoung rtw_intr_ioerror(struct rtw_softc *sc, uint16_t isr) 2086 1.21 dyoung { 2087 1.125 nonaka int s; 2088 1.125 nonaka 2089 1.98 dyoung aprint_error_dev(sc->sc_dev, "tx fifo underflow\n"); 2090 1.5 dyoung 2091 1.83 dyoung RTW_DPRINTF(RTW_DEBUG_BUGS, ("%s: cleaning up xmit, isr %" PRIx16 2092 1.98 dyoung "\n", device_xname(sc->sc_dev), isr)); 2093 1.15 dyoung 2094 1.125 nonaka s = splnet(); 2095 1.125 nonaka 2096 1.24 dyoung #ifdef RTW_DEBUG 2097 1.21 dyoung rtw_dump_rings(sc); 2098 1.24 dyoung #endif /* RTW_DEBUG */ 2099 1.15 dyoung 2100 1.58 dyoung /* Collect tx'd packets. XXX let's hope this stops the transmit 2101 1.58 dyoung * timeouts. 2102 1.58 dyoung */ 2103 1.83 dyoung rtw_txdescs_reset(sc); 2104 1.21 dyoung 2105 1.24 dyoung #ifdef RTW_DEBUG 2106 1.21 dyoung rtw_dump_rings(sc); 2107 1.24 dyoung #endif /* RTW_DEBUG */ 2108 1.125 nonaka 2109 1.125 nonaka splx(s); 2110 1.3 dyoung } 2111 1.3 dyoung 2112 1.61 perry static inline void 2113 1.1 dyoung rtw_suspend_ticks(struct rtw_softc *sc) 2114 1.1 dyoung { 2115 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_TIMEOUT, 2116 1.98 dyoung ("%s: suspending ticks\n", device_xname(sc->sc_dev))); 2117 1.1 dyoung sc->sc_do_tick = 0; 2118 1.1 dyoung } 2119 1.1 dyoung 2120 1.61 perry static inline void 2121 1.1 dyoung rtw_resume_ticks(struct rtw_softc *sc) 2122 1.1 dyoung { 2123 1.115 dyoung uint32_t tsftrl0, tsftrl1, next_tint; 2124 1.1 dyoung 2125 1.1 dyoung tsftrl0 = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 2126 1.1 dyoung 2127 1.1 dyoung tsftrl1 = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 2128 1.115 dyoung next_tint = tsftrl1 + 1000000; 2129 1.115 dyoung RTW_WRITE(&sc->sc_regs, RTW_TINT, next_tint); 2130 1.1 dyoung 2131 1.1 dyoung sc->sc_do_tick = 1; 2132 1.1 dyoung 2133 1.120 christos #ifdef RTW_DEBUG 2134 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_TIMEOUT, 2135 1.21 dyoung ("%s: resume ticks delta %#08x now %#08x next %#08x\n", 2136 1.115 dyoung device_xname(sc->sc_dev), tsftrl1 - tsftrl0, tsftrl1, next_tint)); 2137 1.120 christos #else 2138 1.120 christos __USE(tsftrl0); 2139 1.120 christos #endif 2140 1.1 dyoung } 2141 1.1 dyoung 2142 1.1 dyoung static void 2143 1.1 dyoung rtw_intr_timeout(struct rtw_softc *sc) 2144 1.1 dyoung { 2145 1.125 nonaka int s; 2146 1.125 nonaka 2147 1.125 nonaka s = splnet(); 2148 1.98 dyoung RTW_DPRINTF(RTW_DEBUG_TIMEOUT, ("%s: timeout\n", device_xname(sc->sc_dev))); 2149 1.1 dyoung if (sc->sc_do_tick) 2150 1.1 dyoung rtw_resume_ticks(sc); 2151 1.125 nonaka splx(s); 2152 1.1 dyoung } 2153 1.1 dyoung 2154 1.1 dyoung int 2155 1.1 dyoung rtw_intr(void *arg) 2156 1.1 dyoung { 2157 1.1 dyoung struct rtw_softc *sc = arg; 2158 1.1 dyoung struct rtw_regs *regs = &sc->sc_regs; 2159 1.37 dyoung uint16_t isr; 2160 1.48 dyoung struct ifnet *ifp = &sc->sc_if; 2161 1.1 dyoung 2162 1.1 dyoung /* 2163 1.1 dyoung * If the interface isn't running, the interrupt couldn't 2164 1.1 dyoung * possibly have come from us. 2165 1.1 dyoung */ 2166 1.101 dyoung if ((ifp->if_flags & IFF_RUNNING) == 0 || 2167 1.109 dyoung !device_activation(sc->sc_dev, DEVACT_LEVEL_DRIVER)) { 2168 1.98 dyoung RTW_DPRINTF(RTW_DEBUG_INTR, ("%s: stray interrupt\n", 2169 1.98 dyoung device_xname(sc->sc_dev))); 2170 1.1 dyoung return (0); 2171 1.1 dyoung } 2172 1.1 dyoung 2173 1.125 nonaka isr = RTW_READ16(regs, RTW_ISR); 2174 1.125 nonaka if (isr == 0) 2175 1.125 nonaka return (0); 2176 1.125 nonaka 2177 1.125 nonaka /* Disable interrupts. */ 2178 1.125 nonaka RTW_WRITE16(regs, RTW_IMR, 0); 2179 1.125 nonaka RTW_WBW(regs, RTW_IMR, RTW_IMR); 2180 1.125 nonaka 2181 1.125 nonaka softint_schedule(sc->sc_soft_ih); 2182 1.125 nonaka return (1); 2183 1.125 nonaka } 2184 1.125 nonaka 2185 1.125 nonaka static void 2186 1.125 nonaka rtw_softintr(void *arg) 2187 1.125 nonaka { 2188 1.125 nonaka int i; 2189 1.125 nonaka struct rtw_softc *sc = arg; 2190 1.125 nonaka struct rtw_regs *regs = &sc->sc_regs; 2191 1.125 nonaka uint16_t isr; 2192 1.125 nonaka struct ifnet *ifp = &sc->sc_if; 2193 1.125 nonaka 2194 1.125 nonaka if ((ifp->if_flags & IFF_RUNNING) == 0 || 2195 1.125 nonaka !device_activation(sc->sc_dev, DEVACT_LEVEL_DRIVER)) { 2196 1.125 nonaka RTW_DPRINTF(RTW_DEBUG_INTR, ("%s: stray interrupt\n", 2197 1.125 nonaka device_xname(sc->sc_dev))); 2198 1.125 nonaka return; 2199 1.125 nonaka } 2200 1.125 nonaka 2201 1.3 dyoung for (i = 0; i < 10; i++) { 2202 1.1 dyoung isr = RTW_READ16(regs, RTW_ISR); 2203 1.1 dyoung 2204 1.1 dyoung RTW_WRITE16(regs, RTW_ISR, isr); 2205 1.8 dyoung RTW_WBR(regs, RTW_ISR, RTW_ISR); 2206 1.1 dyoung 2207 1.1 dyoung if (sc->sc_intr_ack != NULL) 2208 1.1 dyoung (*sc->sc_intr_ack)(regs); 2209 1.1 dyoung 2210 1.1 dyoung if (isr == 0) 2211 1.1 dyoung break; 2212 1.1 dyoung 2213 1.1 dyoung #ifdef RTW_DEBUG 2214 1.1 dyoung #define PRINTINTR(flag) do { \ 2215 1.1 dyoung if ((isr & flag) != 0) { \ 2216 1.1 dyoung printf("%s" #flag, delim); \ 2217 1.1 dyoung delim = ","; \ 2218 1.1 dyoung } \ 2219 1.1 dyoung } while (0) 2220 1.1 dyoung 2221 1.21 dyoung if ((rtw_debug & RTW_DEBUG_INTR) != 0 && isr != 0) { 2222 1.1 dyoung const char *delim = "<"; 2223 1.1 dyoung 2224 1.98 dyoung printf("%s: reg[ISR] = %x", device_xname(sc->sc_dev), 2225 1.98 dyoung isr); 2226 1.1 dyoung 2227 1.1 dyoung PRINTINTR(RTW_INTR_TXFOVW); 2228 1.1 dyoung PRINTINTR(RTW_INTR_TIMEOUT); 2229 1.1 dyoung PRINTINTR(RTW_INTR_BCNINT); 2230 1.1 dyoung PRINTINTR(RTW_INTR_ATIMINT); 2231 1.1 dyoung PRINTINTR(RTW_INTR_TBDER); 2232 1.1 dyoung PRINTINTR(RTW_INTR_TBDOK); 2233 1.1 dyoung PRINTINTR(RTW_INTR_THPDER); 2234 1.1 dyoung PRINTINTR(RTW_INTR_THPDOK); 2235 1.1 dyoung PRINTINTR(RTW_INTR_TNPDER); 2236 1.1 dyoung PRINTINTR(RTW_INTR_TNPDOK); 2237 1.1 dyoung PRINTINTR(RTW_INTR_RXFOVW); 2238 1.1 dyoung PRINTINTR(RTW_INTR_RDU); 2239 1.1 dyoung PRINTINTR(RTW_INTR_TLPDER); 2240 1.1 dyoung PRINTINTR(RTW_INTR_TLPDOK); 2241 1.1 dyoung PRINTINTR(RTW_INTR_RER); 2242 1.1 dyoung PRINTINTR(RTW_INTR_ROK); 2243 1.1 dyoung 2244 1.1 dyoung printf(">\n"); 2245 1.1 dyoung } 2246 1.1 dyoung #undef PRINTINTR 2247 1.1 dyoung #endif /* RTW_DEBUG */ 2248 1.1 dyoung 2249 1.1 dyoung if ((isr & RTW_INTR_RX) != 0) 2250 1.83 dyoung rtw_intr_rx(sc, isr); 2251 1.1 dyoung if ((isr & RTW_INTR_TX) != 0) 2252 1.83 dyoung rtw_intr_tx(sc, isr); 2253 1.1 dyoung if ((isr & RTW_INTR_BEACON) != 0) 2254 1.83 dyoung rtw_intr_beacon(sc, isr); 2255 1.1 dyoung if ((isr & RTW_INTR_ATIMINT) != 0) 2256 1.1 dyoung rtw_intr_atim(sc); 2257 1.1 dyoung if ((isr & RTW_INTR_IOERROR) != 0) 2258 1.83 dyoung rtw_intr_ioerror(sc, isr); 2259 1.1 dyoung if ((isr & RTW_INTR_TIMEOUT) != 0) 2260 1.1 dyoung rtw_intr_timeout(sc); 2261 1.1 dyoung } 2262 1.125 nonaka if (i == 10) 2263 1.125 nonaka softint_schedule(sc->sc_soft_ih); 2264 1.1 dyoung 2265 1.125 nonaka /* Re-enable interrupts */ 2266 1.125 nonaka RTW_WRITE16(regs, RTW_IMR, sc->sc_inten); 2267 1.125 nonaka RTW_WBW(regs, RTW_IMR, RTW_IMR); 2268 1.1 dyoung } 2269 1.1 dyoung 2270 1.21 dyoung /* Must be called at splnet. */ 2271 1.1 dyoung static void 2272 1.1 dyoung rtw_stop(struct ifnet *ifp, int disable) 2273 1.1 dyoung { 2274 1.21 dyoung int pri; 2275 1.1 dyoung struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 2276 1.1 dyoung struct ieee80211com *ic = &sc->sc_ic; 2277 1.1 dyoung struct rtw_regs *regs = &sc->sc_regs; 2278 1.1 dyoung 2279 1.1 dyoung rtw_suspend_ticks(sc); 2280 1.1 dyoung 2281 1.1 dyoung ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 2282 1.1 dyoung 2283 1.101 dyoung if (device_has_power(sc->sc_dev)) { 2284 1.3 dyoung /* Disable interrupts. */ 2285 1.3 dyoung RTW_WRITE16(regs, RTW_IMR, 0); 2286 1.3 dyoung 2287 1.8 dyoung RTW_WBW(regs, RTW_TPPOLL, RTW_IMR); 2288 1.8 dyoung 2289 1.3 dyoung /* Stop the transmit and receive processes. First stop DMA, 2290 1.3 dyoung * then disable receiver and transmitter. 2291 1.3 dyoung */ 2292 1.42 dyoung RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 2293 1.1 dyoung 2294 1.8 dyoung RTW_SYNC(regs, RTW_TPPOLL, RTW_IMR); 2295 1.8 dyoung 2296 1.83 dyoung rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0); 2297 1.3 dyoung } 2298 1.1 dyoung 2299 1.5 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 2300 1.34 dyoung rtw_txsofts_release(sc->sc_dmat, &sc->sc_ic, 2301 1.34 dyoung &sc->sc_txsoft_blk[pri]); 2302 1.5 dyoung } 2303 1.1 dyoung 2304 1.34 dyoung rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxsoft[0]); 2305 1.31 dyoung 2306 1.1 dyoung /* Mark the interface as not running. Cancel the watchdog timer. */ 2307 1.21 dyoung ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 2308 1.1 dyoung ifp->if_timer = 0; 2309 1.3 dyoung 2310 1.101 dyoung if (disable) 2311 1.109 dyoung pmf_device_suspend(sc->sc_dev, &sc->sc_qual); 2312 1.101 dyoung 2313 1.1 dyoung return; 2314 1.1 dyoung } 2315 1.1 dyoung 2316 1.1 dyoung const char * 2317 1.1 dyoung rtw_pwrstate_string(enum rtw_pwrstate power) 2318 1.1 dyoung { 2319 1.1 dyoung switch (power) { 2320 1.1 dyoung case RTW_ON: 2321 1.1 dyoung return "on"; 2322 1.1 dyoung case RTW_SLEEP: 2323 1.1 dyoung return "sleep"; 2324 1.1 dyoung case RTW_OFF: 2325 1.1 dyoung return "off"; 2326 1.1 dyoung default: 2327 1.1 dyoung return "unknown"; 2328 1.1 dyoung } 2329 1.1 dyoung } 2330 1.1 dyoung 2331 1.10 dyoung /* XXX For Maxim, I am using the RFMD settings gleaned from the 2332 1.10 dyoung * reference driver, plus a magic Maxim "ON" value that comes from 2333 1.10 dyoung * the Realtek document "Windows PG for Rtl8180." 2334 1.1 dyoung */ 2335 1.1 dyoung static void 2336 1.1 dyoung rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 2337 1.81 christos int before_rf, int digphy) 2338 1.1 dyoung { 2339 1.37 dyoung uint32_t anaparm; 2340 1.1 dyoung 2341 1.10 dyoung anaparm = RTW_READ(regs, RTW_ANAPARM); 2342 1.10 dyoung anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 2343 1.10 dyoung 2344 1.10 dyoung switch (power) { 2345 1.10 dyoung case RTW_OFF: 2346 1.10 dyoung if (before_rf) 2347 1.10 dyoung return; 2348 1.10 dyoung anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF; 2349 1.10 dyoung anaparm |= RTW_ANAPARM_TXDACOFF; 2350 1.10 dyoung break; 2351 1.10 dyoung case RTW_SLEEP: 2352 1.10 dyoung if (!before_rf) 2353 1.10 dyoung return; 2354 1.10 dyoung anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP; 2355 1.10 dyoung anaparm |= RTW_ANAPARM_TXDACOFF; 2356 1.10 dyoung break; 2357 1.10 dyoung case RTW_ON: 2358 1.10 dyoung if (!before_rf) 2359 1.10 dyoung return; 2360 1.10 dyoung anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON; 2361 1.10 dyoung break; 2362 1.10 dyoung } 2363 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_PWR, 2364 1.21 dyoung ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 2365 1.10 dyoung __func__, rtw_pwrstate_string(power), 2366 1.10 dyoung (before_rf) ? "before" : "after", anaparm)); 2367 1.10 dyoung 2368 1.10 dyoung RTW_WRITE(regs, RTW_ANAPARM, anaparm); 2369 1.10 dyoung RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 2370 1.10 dyoung } 2371 1.10 dyoung 2372 1.10 dyoung /* XXX I am using the RFMD settings gleaned from the reference 2373 1.44 perry * driver. They agree 2374 1.10 dyoung */ 2375 1.10 dyoung static void 2376 1.10 dyoung rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 2377 1.81 christos int before_rf, int digphy) 2378 1.10 dyoung { 2379 1.37 dyoung uint32_t anaparm; 2380 1.1 dyoung 2381 1.1 dyoung anaparm = RTW_READ(regs, RTW_ANAPARM); 2382 1.10 dyoung anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 2383 1.1 dyoung 2384 1.1 dyoung switch (power) { 2385 1.1 dyoung case RTW_OFF: 2386 1.1 dyoung if (before_rf) 2387 1.1 dyoung return; 2388 1.10 dyoung anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF; 2389 1.1 dyoung anaparm |= RTW_ANAPARM_TXDACOFF; 2390 1.1 dyoung break; 2391 1.1 dyoung case RTW_SLEEP: 2392 1.1 dyoung if (!before_rf) 2393 1.1 dyoung return; 2394 1.10 dyoung anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP; 2395 1.1 dyoung anaparm |= RTW_ANAPARM_TXDACOFF; 2396 1.1 dyoung break; 2397 1.1 dyoung case RTW_ON: 2398 1.1 dyoung if (!before_rf) 2399 1.1 dyoung return; 2400 1.10 dyoung anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON; 2401 1.1 dyoung break; 2402 1.1 dyoung } 2403 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_PWR, 2404 1.21 dyoung ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 2405 1.10 dyoung __func__, rtw_pwrstate_string(power), 2406 1.10 dyoung (before_rf) ? "before" : "after", anaparm)); 2407 1.10 dyoung 2408 1.1 dyoung RTW_WRITE(regs, RTW_ANAPARM, anaparm); 2409 1.1 dyoung RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 2410 1.1 dyoung } 2411 1.1 dyoung 2412 1.1 dyoung static void 2413 1.1 dyoung rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 2414 1.10 dyoung int before_rf, int digphy) 2415 1.1 dyoung { 2416 1.37 dyoung uint32_t anaparm; 2417 1.1 dyoung 2418 1.1 dyoung anaparm = RTW_READ(regs, RTW_ANAPARM); 2419 1.10 dyoung anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 2420 1.1 dyoung 2421 1.1 dyoung switch (power) { 2422 1.1 dyoung case RTW_OFF: 2423 1.1 dyoung if (before_rf) 2424 1.1 dyoung return; 2425 1.10 dyoung anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF; 2426 1.1 dyoung anaparm |= RTW_ANAPARM_TXDACOFF; 2427 1.1 dyoung break; 2428 1.1 dyoung case RTW_SLEEP: 2429 1.1 dyoung if (!before_rf) 2430 1.1 dyoung return; 2431 1.10 dyoung anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP; 2432 1.1 dyoung anaparm |= RTW_ANAPARM_TXDACOFF; 2433 1.1 dyoung break; 2434 1.1 dyoung case RTW_ON: 2435 1.1 dyoung if (!before_rf) 2436 1.1 dyoung return; 2437 1.10 dyoung if (digphy) { 2438 1.10 dyoung anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON; 2439 1.10 dyoung /* XXX guess */ 2440 1.10 dyoung anaparm |= RTW_ANAPARM_TXDACOFF; 2441 1.10 dyoung } else 2442 1.10 dyoung anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON; 2443 1.1 dyoung break; 2444 1.1 dyoung } 2445 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_PWR, 2446 1.21 dyoung ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 2447 1.10 dyoung __func__, rtw_pwrstate_string(power), 2448 1.10 dyoung (before_rf) ? "before" : "after", anaparm)); 2449 1.10 dyoung 2450 1.1 dyoung RTW_WRITE(regs, RTW_ANAPARM, anaparm); 2451 1.1 dyoung RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 2452 1.1 dyoung } 2453 1.1 dyoung 2454 1.1 dyoung static void 2455 1.10 dyoung rtw_pwrstate0(struct rtw_softc *sc, enum rtw_pwrstate power, int before_rf, 2456 1.10 dyoung int digphy) 2457 1.1 dyoung { 2458 1.1 dyoung struct rtw_regs *regs = &sc->sc_regs; 2459 1.1 dyoung 2460 1.42 dyoung rtw_set_access(regs, RTW_ACCESS_ANAPARM); 2461 1.1 dyoung 2462 1.10 dyoung (*sc->sc_pwrstate_cb)(regs, power, before_rf, digphy); 2463 1.1 dyoung 2464 1.42 dyoung rtw_set_access(regs, RTW_ACCESS_NONE); 2465 1.1 dyoung 2466 1.1 dyoung return; 2467 1.1 dyoung } 2468 1.1 dyoung 2469 1.1 dyoung static int 2470 1.1 dyoung rtw_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power) 2471 1.1 dyoung { 2472 1.1 dyoung int rc; 2473 1.1 dyoung 2474 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_PWR, 2475 1.21 dyoung ("%s: %s->%s\n", __func__, 2476 1.1 dyoung rtw_pwrstate_string(sc->sc_pwrstate), rtw_pwrstate_string(power))); 2477 1.1 dyoung 2478 1.1 dyoung if (sc->sc_pwrstate == power) 2479 1.1 dyoung return 0; 2480 1.1 dyoung 2481 1.10 dyoung rtw_pwrstate0(sc, power, 1, sc->sc_flags & RTW_F_DIGPHY); 2482 1.1 dyoung rc = rtw_rf_pwrstate(sc->sc_rf, power); 2483 1.10 dyoung rtw_pwrstate0(sc, power, 0, sc->sc_flags & RTW_F_DIGPHY); 2484 1.1 dyoung 2485 1.1 dyoung switch (power) { 2486 1.1 dyoung case RTW_ON: 2487 1.4 dyoung /* TBD set LEDs */ 2488 1.1 dyoung break; 2489 1.1 dyoung case RTW_SLEEP: 2490 1.1 dyoung /* TBD */ 2491 1.1 dyoung break; 2492 1.1 dyoung case RTW_OFF: 2493 1.1 dyoung /* TBD */ 2494 1.1 dyoung break; 2495 1.1 dyoung } 2496 1.1 dyoung if (rc == 0) 2497 1.1 dyoung sc->sc_pwrstate = power; 2498 1.1 dyoung else 2499 1.1 dyoung sc->sc_pwrstate = RTW_OFF; 2500 1.1 dyoung return rc; 2501 1.1 dyoung } 2502 1.1 dyoung 2503 1.1 dyoung static int 2504 1.1 dyoung rtw_tune(struct rtw_softc *sc) 2505 1.1 dyoung { 2506 1.1 dyoung struct ieee80211com *ic = &sc->sc_ic; 2507 1.71 dyoung struct rtw_tx_radiotap_header *rt = &sc->sc_txtap; 2508 1.71 dyoung struct rtw_rx_radiotap_header *rr = &sc->sc_rxtap; 2509 1.1 dyoung u_int chan; 2510 1.1 dyoung int rc; 2511 1.1 dyoung int antdiv = sc->sc_flags & RTW_F_ANTDIV, 2512 1.1 dyoung dflantb = sc->sc_flags & RTW_F_DFLANTB; 2513 1.1 dyoung 2514 1.57 skrll chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2515 1.97 dyoung KASSERT(chan != IEEE80211_CHAN_ANY); 2516 1.1 dyoung 2517 1.71 dyoung rt->rt_chan_freq = htole16(ic->ic_curchan->ic_freq); 2518 1.71 dyoung rt->rt_chan_flags = htole16(ic->ic_curchan->ic_flags); 2519 1.71 dyoung 2520 1.71 dyoung rr->rr_chan_freq = htole16(ic->ic_curchan->ic_freq); 2521 1.71 dyoung rr->rr_chan_flags = htole16(ic->ic_curchan->ic_flags); 2522 1.71 dyoung 2523 1.1 dyoung if (chan == sc->sc_cur_chan) { 2524 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_TUNE, 2525 1.44 perry ("%s: already tuned chan #%d\n", __func__, chan)); 2526 1.1 dyoung return 0; 2527 1.1 dyoung } 2528 1.1 dyoung 2529 1.1 dyoung rtw_suspend_ticks(sc); 2530 1.1 dyoung 2531 1.83 dyoung rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0); 2532 1.1 dyoung 2533 1.1 dyoung /* TBD wait for Tx to complete */ 2534 1.1 dyoung 2535 1.101 dyoung KASSERT(device_has_power(sc->sc_dev)); 2536 1.1 dyoung 2537 1.1 dyoung if ((rc = rtw_phy_init(&sc->sc_regs, sc->sc_rf, 2538 1.57 skrll rtw_chan2txpower(&sc->sc_srom, ic, ic->ic_curchan), sc->sc_csthr, 2539 1.132 msaitoh ic->ic_curchan->ic_freq, antdiv, dflantb, RTW_ON)) != 0) { 2540 1.1 dyoung /* XXX condition on powersaving */ 2541 1.98 dyoung aprint_error_dev(sc->sc_dev, "phy init failed\n"); 2542 1.1 dyoung } 2543 1.1 dyoung 2544 1.1 dyoung sc->sc_cur_chan = chan; 2545 1.1 dyoung 2546 1.83 dyoung rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1); 2547 1.1 dyoung 2548 1.1 dyoung rtw_resume_ticks(sc); 2549 1.1 dyoung 2550 1.1 dyoung return rc; 2551 1.1 dyoung } 2552 1.1 dyoung 2553 1.101 dyoung bool 2554 1.114 dyoung rtw_suspend(device_t self, const pmf_qual_t *qual) 2555 1.1 dyoung { 2556 1.1 dyoung int rc; 2557 1.101 dyoung struct rtw_softc *sc = device_private(self); 2558 1.101 dyoung 2559 1.101 dyoung sc->sc_flags &= ~RTW_F_DK_VALID; 2560 1.1 dyoung 2561 1.101 dyoung if (!device_has_power(self)) 2562 1.101 dyoung return false; 2563 1.1 dyoung 2564 1.1 dyoung /* turn off PHY */ 2565 1.101 dyoung if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0) { 2566 1.101 dyoung aprint_error_dev(self, "failed to turn off PHY (%d)\n", rc); 2567 1.101 dyoung return false; 2568 1.36 dyoung } 2569 1.1 dyoung 2570 1.101 dyoung rtw_disable_interrupts(&sc->sc_regs); 2571 1.1 dyoung 2572 1.101 dyoung return true; 2573 1.1 dyoung } 2574 1.1 dyoung 2575 1.101 dyoung bool 2576 1.114 dyoung rtw_resume(device_t self, const pmf_qual_t *qual) 2577 1.1 dyoung { 2578 1.101 dyoung struct rtw_softc *sc = device_private(self); 2579 1.101 dyoung 2580 1.101 dyoung /* Power may have been removed, resetting WEP keys. 2581 1.101 dyoung */ 2582 1.101 dyoung sc->sc_flags &= ~RTW_F_DK_VALID; 2583 1.101 dyoung rtw_enable_interrupts(sc); 2584 1.101 dyoung 2585 1.101 dyoung return true; 2586 1.1 dyoung } 2587 1.1 dyoung 2588 1.1 dyoung static void 2589 1.1 dyoung rtw_transmit_config(struct rtw_regs *regs) 2590 1.1 dyoung { 2591 1.37 dyoung uint32_t tcr; 2592 1.1 dyoung 2593 1.1 dyoung tcr = RTW_READ(regs, RTW_TCR); 2594 1.1 dyoung 2595 1.10 dyoung tcr |= RTW_TCR_CWMIN; 2596 1.10 dyoung tcr &= ~RTW_TCR_MXDMA_MASK; 2597 1.10 dyoung tcr |= RTW_TCR_MXDMA_256; 2598 1.1 dyoung tcr |= RTW_TCR_SAT; /* send ACK as fast as possible */ 2599 1.1 dyoung tcr &= ~RTW_TCR_LBK_MASK; 2600 1.1 dyoung tcr |= RTW_TCR_LBK_NORMAL; /* normal operating mode */ 2601 1.1 dyoung 2602 1.1 dyoung /* set short/long retry limits */ 2603 1.131 msaitoh tcr &= ~(RTW_TCR_SRL_MASK | RTW_TCR_LRL_MASK); 2604 1.75 dyoung tcr |= __SHIFTIN(4, RTW_TCR_SRL_MASK) | __SHIFTIN(4, RTW_TCR_LRL_MASK); 2605 1.1 dyoung 2606 1.13 dyoung tcr &= ~RTW_TCR_CRC; /* NIC appends CRC32 */ 2607 1.1 dyoung 2608 1.1 dyoung RTW_WRITE(regs, RTW_TCR, tcr); 2609 1.8 dyoung RTW_SYNC(regs, RTW_TCR, RTW_TCR); 2610 1.1 dyoung } 2611 1.1 dyoung 2612 1.101 dyoung static void 2613 1.101 dyoung rtw_disable_interrupts(struct rtw_regs *regs) 2614 1.101 dyoung { 2615 1.101 dyoung RTW_WRITE16(regs, RTW_IMR, 0); 2616 1.101 dyoung RTW_WBW(regs, RTW_IMR, RTW_ISR); 2617 1.101 dyoung RTW_WRITE16(regs, RTW_ISR, 0xffff); 2618 1.101 dyoung RTW_SYNC(regs, RTW_IMR, RTW_ISR); 2619 1.101 dyoung } 2620 1.101 dyoung 2621 1.101 dyoung static void 2622 1.1 dyoung rtw_enable_interrupts(struct rtw_softc *sc) 2623 1.1 dyoung { 2624 1.1 dyoung struct rtw_regs *regs = &sc->sc_regs; 2625 1.1 dyoung 2626 1.131 msaitoh sc->sc_inten = RTW_INTR_RX | RTW_INTR_TX | RTW_INTR_BEACON 2627 1.131 msaitoh | RTW_INTR_ATIMINT; 2628 1.131 msaitoh sc->sc_inten |= RTW_INTR_IOERROR | RTW_INTR_TIMEOUT; 2629 1.1 dyoung 2630 1.1 dyoung RTW_WRITE16(regs, RTW_IMR, sc->sc_inten); 2631 1.8 dyoung RTW_WBW(regs, RTW_IMR, RTW_ISR); 2632 1.1 dyoung RTW_WRITE16(regs, RTW_ISR, 0xffff); 2633 1.8 dyoung RTW_SYNC(regs, RTW_IMR, RTW_ISR); 2634 1.1 dyoung 2635 1.1 dyoung /* XXX necessary? */ 2636 1.1 dyoung if (sc->sc_intr_ack != NULL) 2637 1.1 dyoung (*sc->sc_intr_ack)(regs); 2638 1.1 dyoung } 2639 1.1 dyoung 2640 1.10 dyoung static void 2641 1.10 dyoung rtw_set_nettype(struct rtw_softc *sc, enum ieee80211_opmode opmode) 2642 1.10 dyoung { 2643 1.10 dyoung uint8_t msr; 2644 1.10 dyoung 2645 1.10 dyoung /* I'm guessing that MSR is protected as CONFIG[0123] are. */ 2646 1.42 dyoung rtw_set_access(&sc->sc_regs, RTW_ACCESS_CONFIG); 2647 1.10 dyoung 2648 1.10 dyoung msr = RTW_READ8(&sc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK; 2649 1.10 dyoung 2650 1.10 dyoung switch (opmode) { 2651 1.10 dyoung case IEEE80211_M_AHDEMO: 2652 1.10 dyoung case IEEE80211_M_IBSS: 2653 1.10 dyoung msr |= RTW_MSR_NETYPE_ADHOC_OK; 2654 1.10 dyoung break; 2655 1.10 dyoung case IEEE80211_M_HOSTAP: 2656 1.10 dyoung msr |= RTW_MSR_NETYPE_AP_OK; 2657 1.10 dyoung break; 2658 1.10 dyoung case IEEE80211_M_MONITOR: 2659 1.10 dyoung /* XXX */ 2660 1.10 dyoung msr |= RTW_MSR_NETYPE_NOLINK; 2661 1.10 dyoung break; 2662 1.10 dyoung case IEEE80211_M_STA: 2663 1.10 dyoung msr |= RTW_MSR_NETYPE_INFRA_OK; 2664 1.10 dyoung break; 2665 1.10 dyoung } 2666 1.10 dyoung RTW_WRITE8(&sc->sc_regs, RTW_MSR, msr); 2667 1.10 dyoung 2668 1.42 dyoung rtw_set_access(&sc->sc_regs, RTW_ACCESS_NONE); 2669 1.10 dyoung } 2670 1.10 dyoung 2671 1.1 dyoung #define rtw_calchash(addr) \ 2672 1.38 dyoung (ether_crc32_be((addr), IEEE80211_ADDR_LEN) >> 26) 2673 1.1 dyoung 2674 1.1 dyoung static void 2675 1.1 dyoung rtw_pktfilt_load(struct rtw_softc *sc) 2676 1.1 dyoung { 2677 1.1 dyoung struct rtw_regs *regs = &sc->sc_regs; 2678 1.1 dyoung struct ieee80211com *ic = &sc->sc_ic; 2679 1.48 dyoung struct ethercom *ec = &sc->sc_ec; 2680 1.48 dyoung struct ifnet *ifp = &sc->sc_if; 2681 1.1 dyoung int hash; 2682 1.37 dyoung uint32_t hashes[2] = { 0, 0 }; 2683 1.1 dyoung struct ether_multi *enm; 2684 1.1 dyoung struct ether_multistep step; 2685 1.1 dyoung 2686 1.1 dyoung /* XXX might be necessary to stop Rx/Tx engines while setting filters */ 2687 1.1 dyoung 2688 1.38 dyoung sc->sc_rcr &= ~RTW_RCR_PKTFILTER_MASK; 2689 1.38 dyoung sc->sc_rcr &= ~(RTW_RCR_MXDMA_MASK | RTW_RCR_RXFTH_MASK); 2690 1.1 dyoung 2691 1.38 dyoung sc->sc_rcr |= RTW_RCR_PKTFILTER_DEFAULT; 2692 1.38 dyoung /* MAC auto-reset PHY (huh?) */ 2693 1.10 dyoung sc->sc_rcr |= RTW_RCR_ENMARP; 2694 1.38 dyoung /* DMA whole Rx packets, only. Set Tx DMA burst size to 1024 bytes. */ 2695 1.38 dyoung sc->sc_rcr |= RTW_RCR_MXDMA_1024 | RTW_RCR_RXFTH_WHOLE; 2696 1.1 dyoung 2697 1.38 dyoung switch (ic->ic_opmode) { 2698 1.38 dyoung case IEEE80211_M_MONITOR: 2699 1.38 dyoung sc->sc_rcr |= RTW_RCR_MONITOR; 2700 1.38 dyoung break; 2701 1.38 dyoung case IEEE80211_M_AHDEMO: 2702 1.38 dyoung case IEEE80211_M_IBSS: 2703 1.38 dyoung /* receive broadcasts in our BSS */ 2704 1.38 dyoung sc->sc_rcr |= RTW_RCR_ADD3; 2705 1.38 dyoung break; 2706 1.38 dyoung default: 2707 1.38 dyoung break; 2708 1.38 dyoung } 2709 1.1 dyoung 2710 1.1 dyoung ifp->if_flags &= ~IFF_ALLMULTI; 2711 1.1 dyoung 2712 1.1 dyoung /* 2713 1.1 dyoung * Program the 64-bit multicast hash filter. 2714 1.1 dyoung */ 2715 1.133 msaitoh ETHER_LOCK(ec); 2716 1.1 dyoung ETHER_FIRST_MULTI(step, ec, enm); 2717 1.1 dyoung while (enm != NULL) { 2718 1.1 dyoung /* XXX */ 2719 1.1 dyoung if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 2720 1.86 dyoung ETHER_ADDR_LEN) != 0) { 2721 1.86 dyoung ifp->if_flags |= IFF_ALLMULTI; 2722 1.86 dyoung break; 2723 1.86 dyoung } 2724 1.1 dyoung 2725 1.1 dyoung hash = rtw_calchash(enm->enm_addrlo); 2726 1.38 dyoung hashes[hash >> 5] |= (1 << (hash & 0x1f)); 2727 1.1 dyoung ETHER_NEXT_MULTI(step, enm); 2728 1.1 dyoung } 2729 1.133 msaitoh ETHER_UNLOCK(ec); 2730 1.1 dyoung 2731 1.86 dyoung /* XXX accept all broadcast if scanning */ 2732 1.86 dyoung if ((ifp->if_flags & IFF_BROADCAST) != 0) 2733 1.86 dyoung sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */ 2734 1.86 dyoung 2735 1.86 dyoung if (ifp->if_flags & IFF_PROMISC) { 2736 1.86 dyoung sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */ 2737 1.93 dyoung sc->sc_rcr |= RTW_RCR_ACRC32; /* accept frames failing CRC */ 2738 1.93 dyoung sc->sc_rcr |= RTW_RCR_AICV; /* accept frames failing ICV */ 2739 1.86 dyoung ifp->if_flags |= IFF_ALLMULTI; 2740 1.86 dyoung } 2741 1.86 dyoung 2742 1.86 dyoung if (ifp->if_flags & IFF_ALLMULTI) 2743 1.38 dyoung hashes[0] = hashes[1] = 0xffffffff; 2744 1.86 dyoung 2745 1.86 dyoung if ((hashes[0] | hashes[1]) != 0) 2746 1.86 dyoung sc->sc_rcr |= RTW_RCR_AM; /* accept multicast */ 2747 1.1 dyoung 2748 1.1 dyoung RTW_WRITE(regs, RTW_MAR0, hashes[0]); 2749 1.1 dyoung RTW_WRITE(regs, RTW_MAR1, hashes[1]); 2750 1.1 dyoung RTW_WRITE(regs, RTW_RCR, sc->sc_rcr); 2751 1.1 dyoung RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */ 2752 1.1 dyoung 2753 1.21 dyoung DPRINTF(sc, RTW_DEBUG_PKTFILT, 2754 1.21 dyoung ("%s: RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n", 2755 1.98 dyoung device_xname(sc->sc_dev), RTW_READ(regs, RTW_MAR0), 2756 1.1 dyoung RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR))); 2757 1.1 dyoung } 2758 1.1 dyoung 2759 1.42 dyoung static struct mbuf * 2760 1.42 dyoung rtw_beacon_alloc(struct rtw_softc *sc, struct ieee80211_node *ni) 2761 1.42 dyoung { 2762 1.42 dyoung struct ieee80211com *ic = &sc->sc_ic; 2763 1.42 dyoung struct mbuf *m; 2764 1.48 dyoung struct ieee80211_beacon_offsets boff; 2765 1.42 dyoung 2766 1.58 dyoung if ((m = ieee80211_beacon_alloc(ic, ni, &boff)) != NULL) { 2767 1.58 dyoung RTW_DPRINTF(RTW_DEBUG_BEACON, 2768 1.58 dyoung ("%s: m %p len %u\n", __func__, m, m->m_len)); 2769 1.58 dyoung } 2770 1.42 dyoung return m; 2771 1.42 dyoung } 2772 1.42 dyoung 2773 1.21 dyoung /* Must be called at splnet. */ 2774 1.1 dyoung static int 2775 1.1 dyoung rtw_init(struct ifnet *ifp) 2776 1.1 dyoung { 2777 1.1 dyoung struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 2778 1.1 dyoung struct ieee80211com *ic = &sc->sc_ic; 2779 1.1 dyoung struct rtw_regs *regs = &sc->sc_regs; 2780 1.101 dyoung int rc; 2781 1.1 dyoung 2782 1.101 dyoung if (device_is_active(sc->sc_dev)) { 2783 1.101 dyoung /* Cancel pending I/O and reset. */ 2784 1.101 dyoung rtw_stop(ifp, 0); 2785 1.109 dyoung } else if (!pmf_device_resume(sc->sc_dev, &sc->sc_qual) || 2786 1.132 msaitoh !device_is_active(sc->sc_dev)) 2787 1.109 dyoung return 0; 2788 1.1 dyoung 2789 1.21 dyoung DPRINTF(sc, RTW_DEBUG_TUNE, ("%s: channel %d freq %d flags 0x%04x\n", 2790 1.57 skrll __func__, ieee80211_chan2ieee(ic, ic->ic_curchan), 2791 1.57 skrll ic->ic_curchan->ic_freq, ic->ic_curchan->ic_flags)); 2792 1.1 dyoung 2793 1.1 dyoung if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0) 2794 1.1 dyoung goto out; 2795 1.1 dyoung 2796 1.31 dyoung if ((rc = rtw_swring_setup(sc)) != 0) 2797 1.31 dyoung goto out; 2798 1.1 dyoung 2799 1.1 dyoung rtw_transmit_config(regs); 2800 1.1 dyoung 2801 1.42 dyoung rtw_set_access(regs, RTW_ACCESS_CONFIG); 2802 1.1 dyoung 2803 1.4 dyoung RTW_WRITE8(regs, RTW_MSR, 0x0); /* no link */ 2804 1.8 dyoung RTW_WBW(regs, RTW_MSR, RTW_BRSR); 2805 1.1 dyoung 2806 1.27 mycroft /* long PLCP header, 1Mb/2Mb basic rate */ 2807 1.27 mycroft RTW_WRITE16(regs, RTW_BRSR, RTW_BRSR_MBR8180_2MBPS); 2808 1.8 dyoung RTW_SYNC(regs, RTW_BRSR, RTW_BRSR); 2809 1.1 dyoung 2810 1.42 dyoung rtw_set_access(regs, RTW_ACCESS_ANAPARM); 2811 1.42 dyoung rtw_set_access(regs, RTW_ACCESS_NONE); 2812 1.1 dyoung 2813 1.1 dyoung /* XXX from reference sources */ 2814 1.1 dyoung RTW_WRITE(regs, RTW_FEMR, 0xffff); 2815 1.8 dyoung RTW_SYNC(regs, RTW_FEMR, RTW_FEMR); 2816 1.1 dyoung 2817 1.98 dyoung rtw_set_rfprog(regs, sc->sc_rfchipid, sc->sc_dev); 2818 1.4 dyoung 2819 1.4 dyoung RTW_WRITE8(regs, RTW_PHYDELAY, sc->sc_phydelay); 2820 1.1 dyoung /* from Linux driver */ 2821 1.4 dyoung RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC); 2822 1.1 dyoung 2823 1.8 dyoung RTW_SYNC(regs, RTW_PHYDELAY, RTW_CRCOUNT); 2824 1.8 dyoung 2825 1.1 dyoung rtw_enable_interrupts(sc); 2826 1.1 dyoung 2827 1.1 dyoung rtw_pktfilt_load(sc); 2828 1.1 dyoung 2829 1.3 dyoung rtw_hwring_setup(sc); 2830 1.1 dyoung 2831 1.48 dyoung rtw_wep_setkeys(sc, ic->ic_nw_keys, ic->ic_def_txkey); 2832 1.42 dyoung 2833 1.83 dyoung rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1); 2834 1.1 dyoung 2835 1.1 dyoung ifp->if_flags |= IFF_RUNNING; 2836 1.1 dyoung ic->ic_state = IEEE80211_S_INIT; 2837 1.1 dyoung 2838 1.1 dyoung RTW_WRITE16(regs, RTW_BSSID16, 0x0); 2839 1.1 dyoung RTW_WRITE(regs, RTW_BSSID32, 0x0); 2840 1.1 dyoung 2841 1.4 dyoung rtw_resume_ticks(sc); 2842 1.1 dyoung 2843 1.10 dyoung rtw_set_nettype(sc, IEEE80211_M_MONITOR); 2844 1.4 dyoung 2845 1.4 dyoung if (ic->ic_opmode == IEEE80211_M_MONITOR) 2846 1.4 dyoung return ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 2847 1.4 dyoung else 2848 1.4 dyoung return ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2849 1.4 dyoung 2850 1.1 dyoung out: 2851 1.98 dyoung aprint_error_dev(sc->sc_dev, "interface not running\n"); 2852 1.1 dyoung return rc; 2853 1.1 dyoung } 2854 1.1 dyoung 2855 1.61 perry static inline void 2856 1.42 dyoung rtw_led_init(struct rtw_regs *regs) 2857 1.42 dyoung { 2858 1.42 dyoung uint8_t cfg0, cfg1; 2859 1.42 dyoung 2860 1.42 dyoung rtw_set_access(regs, RTW_ACCESS_CONFIG); 2861 1.42 dyoung 2862 1.42 dyoung cfg0 = RTW_READ8(regs, RTW_CONFIG0); 2863 1.42 dyoung cfg0 |= RTW_CONFIG0_LEDGPOEN; 2864 1.42 dyoung RTW_WRITE8(regs, RTW_CONFIG0, cfg0); 2865 1.42 dyoung 2866 1.42 dyoung cfg1 = RTW_READ8(regs, RTW_CONFIG1); 2867 1.42 dyoung RTW_DPRINTF(RTW_DEBUG_LED, 2868 1.42 dyoung ("%s: read %" PRIx8 " from reg[CONFIG1]\n", __func__, cfg1)); 2869 1.42 dyoung 2870 1.42 dyoung cfg1 &= ~RTW_CONFIG1_LEDS_MASK; 2871 1.42 dyoung cfg1 |= RTW_CONFIG1_LEDS_TX_RX; 2872 1.42 dyoung RTW_WRITE8(regs, RTW_CONFIG1, cfg1); 2873 1.42 dyoung 2874 1.42 dyoung rtw_set_access(regs, RTW_ACCESS_NONE); 2875 1.42 dyoung } 2876 1.42 dyoung 2877 1.44 perry /* 2878 1.132 msaitoh * IEEE80211_S_INIT: LED1 off 2879 1.42 dyoung * 2880 1.42 dyoung * IEEE80211_S_AUTH, 2881 1.42 dyoung * IEEE80211_S_ASSOC, 2882 1.132 msaitoh * IEEE80211_S_SCAN: LED1 blinks @ 1 Hz, blinks at 5Hz for tx/rx 2883 1.42 dyoung * 2884 1.132 msaitoh * IEEE80211_S_RUN: LED1 on, blinks @ 5Hz for tx/rx 2885 1.42 dyoung */ 2886 1.42 dyoung static void 2887 1.42 dyoung rtw_led_newstate(struct rtw_softc *sc, enum ieee80211_state nstate) 2888 1.42 dyoung { 2889 1.42 dyoung struct rtw_led_state *ls; 2890 1.42 dyoung 2891 1.42 dyoung ls = &sc->sc_led_state; 2892 1.42 dyoung 2893 1.42 dyoung switch (nstate) { 2894 1.42 dyoung case IEEE80211_S_INIT: 2895 1.42 dyoung rtw_led_init(&sc->sc_regs); 2896 1.101 dyoung aprint_debug_dev(sc->sc_dev, "stopping blink\n"); 2897 1.42 dyoung callout_stop(&ls->ls_slow_ch); 2898 1.42 dyoung callout_stop(&ls->ls_fast_ch); 2899 1.42 dyoung ls->ls_slowblink = 0; 2900 1.42 dyoung ls->ls_actblink = 0; 2901 1.42 dyoung ls->ls_default = 0; 2902 1.42 dyoung break; 2903 1.42 dyoung case IEEE80211_S_SCAN: 2904 1.101 dyoung aprint_debug_dev(sc->sc_dev, "scheduling blink\n"); 2905 1.42 dyoung callout_schedule(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS); 2906 1.42 dyoung callout_schedule(&ls->ls_fast_ch, RTW_LED_FAST_TICKS); 2907 1.42 dyoung /*FALLTHROUGH*/ 2908 1.42 dyoung case IEEE80211_S_AUTH: 2909 1.42 dyoung case IEEE80211_S_ASSOC: 2910 1.42 dyoung ls->ls_default = RTW_LED1; 2911 1.42 dyoung ls->ls_actblink = RTW_LED1; 2912 1.42 dyoung ls->ls_slowblink = RTW_LED1; 2913 1.42 dyoung break; 2914 1.42 dyoung case IEEE80211_S_RUN: 2915 1.42 dyoung ls->ls_slowblink = 0; 2916 1.42 dyoung break; 2917 1.42 dyoung } 2918 1.42 dyoung rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); 2919 1.42 dyoung } 2920 1.42 dyoung 2921 1.42 dyoung static void 2922 1.42 dyoung rtw_led_set(struct rtw_led_state *ls, struct rtw_regs *regs, int hwverid) 2923 1.42 dyoung { 2924 1.42 dyoung uint8_t led_condition; 2925 1.42 dyoung bus_size_t ofs; 2926 1.42 dyoung uint8_t mask, newval, val; 2927 1.42 dyoung 2928 1.42 dyoung led_condition = ls->ls_default; 2929 1.42 dyoung 2930 1.42 dyoung if (ls->ls_state & RTW_LED_S_SLOW) 2931 1.42 dyoung led_condition ^= ls->ls_slowblink; 2932 1.131 msaitoh if (ls->ls_state & (RTW_LED_S_RX | RTW_LED_S_TX)) 2933 1.42 dyoung led_condition ^= ls->ls_actblink; 2934 1.42 dyoung 2935 1.42 dyoung RTW_DPRINTF(RTW_DEBUG_LED, 2936 1.42 dyoung ("%s: LED condition %" PRIx8 "\n", __func__, led_condition)); 2937 1.42 dyoung 2938 1.42 dyoung switch (hwverid) { 2939 1.42 dyoung default: 2940 1.42 dyoung case 'F': 2941 1.42 dyoung ofs = RTW_PSR; 2942 1.42 dyoung newval = mask = RTW_PSR_LEDGPO0 | RTW_PSR_LEDGPO1; 2943 1.42 dyoung if (led_condition & RTW_LED0) 2944 1.42 dyoung newval &= ~RTW_PSR_LEDGPO0; 2945 1.42 dyoung if (led_condition & RTW_LED1) 2946 1.42 dyoung newval &= ~RTW_PSR_LEDGPO1; 2947 1.42 dyoung break; 2948 1.42 dyoung case 'D': 2949 1.42 dyoung ofs = RTW_9346CR; 2950 1.42 dyoung mask = RTW_9346CR_EEM_MASK | RTW_9346CR_EEDI | RTW_9346CR_EECS; 2951 1.42 dyoung newval = RTW_9346CR_EEM_PROGRAM; 2952 1.42 dyoung if (led_condition & RTW_LED0) 2953 1.42 dyoung newval |= RTW_9346CR_EEDI; 2954 1.42 dyoung if (led_condition & RTW_LED1) 2955 1.42 dyoung newval |= RTW_9346CR_EECS; 2956 1.42 dyoung break; 2957 1.42 dyoung } 2958 1.42 dyoung val = RTW_READ8(regs, ofs); 2959 1.42 dyoung RTW_DPRINTF(RTW_DEBUG_LED, 2960 1.45 dyoung ("%s: read %" PRIx8 " from reg[%#02" PRIxPTR "]\n", __func__, val, 2961 1.45 dyoung (uintptr_t)ofs)); 2962 1.42 dyoung val &= ~mask; 2963 1.42 dyoung val |= newval; 2964 1.42 dyoung RTW_WRITE8(regs, ofs, val); 2965 1.42 dyoung RTW_DPRINTF(RTW_DEBUG_LED, 2966 1.45 dyoung ("%s: wrote %" PRIx8 " to reg[%#02" PRIxPTR "]\n", __func__, val, 2967 1.45 dyoung (uintptr_t)ofs)); 2968 1.42 dyoung RTW_SYNC(regs, ofs, ofs); 2969 1.42 dyoung } 2970 1.42 dyoung 2971 1.42 dyoung static void 2972 1.42 dyoung rtw_led_fastblink(void *arg) 2973 1.42 dyoung { 2974 1.42 dyoung int ostate, s; 2975 1.42 dyoung struct rtw_softc *sc = (struct rtw_softc *)arg; 2976 1.42 dyoung struct rtw_led_state *ls = &sc->sc_led_state; 2977 1.42 dyoung 2978 1.42 dyoung s = splnet(); 2979 1.42 dyoung ostate = ls->ls_state; 2980 1.42 dyoung ls->ls_state ^= ls->ls_event; 2981 1.42 dyoung 2982 1.42 dyoung if ((ls->ls_event & RTW_LED_S_TX) == 0) 2983 1.42 dyoung ls->ls_state &= ~RTW_LED_S_TX; 2984 1.42 dyoung 2985 1.42 dyoung if ((ls->ls_event & RTW_LED_S_RX) == 0) 2986 1.42 dyoung ls->ls_state &= ~RTW_LED_S_RX; 2987 1.42 dyoung 2988 1.42 dyoung ls->ls_event = 0; 2989 1.42 dyoung 2990 1.42 dyoung if (ostate != ls->ls_state) 2991 1.42 dyoung rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); 2992 1.42 dyoung splx(s); 2993 1.42 dyoung 2994 1.101 dyoung aprint_debug_dev(sc->sc_dev, "scheduling fast blink\n"); 2995 1.42 dyoung callout_schedule(&ls->ls_fast_ch, RTW_LED_FAST_TICKS); 2996 1.42 dyoung } 2997 1.42 dyoung 2998 1.42 dyoung static void 2999 1.42 dyoung rtw_led_slowblink(void *arg) 3000 1.42 dyoung { 3001 1.42 dyoung int s; 3002 1.42 dyoung struct rtw_softc *sc = (struct rtw_softc *)arg; 3003 1.42 dyoung struct rtw_led_state *ls = &sc->sc_led_state; 3004 1.42 dyoung 3005 1.42 dyoung s = splnet(); 3006 1.42 dyoung ls->ls_state ^= RTW_LED_S_SLOW; 3007 1.42 dyoung rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); 3008 1.42 dyoung splx(s); 3009 1.101 dyoung aprint_debug_dev(sc->sc_dev, "scheduling slow blink\n"); 3010 1.42 dyoung callout_schedule(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS); 3011 1.42 dyoung } 3012 1.42 dyoung 3013 1.101 dyoung static void 3014 1.101 dyoung rtw_led_detach(struct rtw_led_state *ls) 3015 1.101 dyoung { 3016 1.101 dyoung callout_destroy(&ls->ls_fast_ch); 3017 1.101 dyoung callout_destroy(&ls->ls_slow_ch); 3018 1.101 dyoung } 3019 1.101 dyoung 3020 1.101 dyoung static void 3021 1.45 dyoung rtw_led_attach(struct rtw_led_state *ls, void *arg) 3022 1.42 dyoung { 3023 1.89 ad callout_init(&ls->ls_fast_ch, 0); 3024 1.89 ad callout_init(&ls->ls_slow_ch, 0); 3025 1.45 dyoung callout_setfunc(&ls->ls_fast_ch, rtw_led_fastblink, arg); 3026 1.45 dyoung callout_setfunc(&ls->ls_slow_ch, rtw_led_slowblink, arg); 3027 1.42 dyoung } 3028 1.42 dyoung 3029 1.1 dyoung static int 3030 1.85 christos rtw_ioctl(struct ifnet *ifp, u_long cmd, void *data) 3031 1.1 dyoung { 3032 1.21 dyoung int rc = 0, s; 3033 1.1 dyoung struct rtw_softc *sc = ifp->if_softc; 3034 1.1 dyoung 3035 1.21 dyoung s = splnet(); 3036 1.86 dyoung if (cmd == SIOCSIFFLAGS) { 3037 1.105 dyoung if ((rc = ifioctl_common(ifp, cmd, data)) != 0) 3038 1.105 dyoung ; 3039 1.131 msaitoh else switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { 3040 1.109 dyoung case IFF_UP: 3041 1.109 dyoung rc = rtw_init(ifp); 3042 1.109 dyoung RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__); 3043 1.109 dyoung break; 3044 1.131 msaitoh case IFF_UP | IFF_RUNNING: 3045 1.109 dyoung if (device_activation(sc->sc_dev, DEVACT_LEVEL_DRIVER)) 3046 1.1 dyoung rtw_pktfilt_load(sc); 3047 1.39 dyoung RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__); 3048 1.109 dyoung break; 3049 1.109 dyoung case IFF_RUNNING: 3050 1.39 dyoung RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__); 3051 1.1 dyoung rtw_stop(ifp, 1); 3052 1.109 dyoung break; 3053 1.109 dyoung default: 3054 1.109 dyoung break; 3055 1.1 dyoung } 3056 1.86 dyoung } else if ((rc = ieee80211_ioctl(&sc->sc_ic, cmd, data)) != ENETRESET) 3057 1.86 dyoung ; /* nothing to do */ 3058 1.86 dyoung else if (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI) { 3059 1.86 dyoung /* reload packet filter if running */ 3060 1.39 dyoung if (ifp->if_flags & IFF_RUNNING) 3061 1.39 dyoung rtw_pktfilt_load(sc); 3062 1.39 dyoung rc = 0; 3063 1.101 dyoung } else if ((ifp->if_flags & IFF_UP) != 0) 3064 1.86 dyoung rc = rtw_init(ifp); 3065 1.86 dyoung else 3066 1.86 dyoung rc = 0; 3067 1.21 dyoung splx(s); 3068 1.1 dyoung return rc; 3069 1.1 dyoung } 3070 1.1 dyoung 3071 1.42 dyoung /* Select a transmit ring with at least one h/w and s/w descriptor free. 3072 1.42 dyoung * Return 0 on success, -1 on failure. 3073 1.42 dyoung */ 3074 1.61 perry static inline int 3075 1.42 dyoung rtw_txring_choose(struct rtw_softc *sc, struct rtw_txsoft_blk **tsbp, 3076 1.42 dyoung struct rtw_txdesc_blk **tdbp, int pri) 3077 1.42 dyoung { 3078 1.42 dyoung struct rtw_txsoft_blk *tsb; 3079 1.42 dyoung struct rtw_txdesc_blk *tdb; 3080 1.42 dyoung 3081 1.42 dyoung KASSERT(pri >= 0 && pri < RTW_NTXPRI); 3082 1.42 dyoung 3083 1.42 dyoung tsb = &sc->sc_txsoft_blk[pri]; 3084 1.42 dyoung tdb = &sc->sc_txdesc_blk[pri]; 3085 1.42 dyoung 3086 1.42 dyoung if (SIMPLEQ_EMPTY(&tsb->tsb_freeq) || tdb->tdb_nfree == 0) { 3087 1.58 dyoung if (tsb->tsb_tx_timer == 0) 3088 1.58 dyoung tsb->tsb_tx_timer = 5; 3089 1.42 dyoung *tsbp = NULL; 3090 1.42 dyoung *tdbp = NULL; 3091 1.42 dyoung return -1; 3092 1.42 dyoung } 3093 1.42 dyoung *tsbp = tsb; 3094 1.42 dyoung *tdbp = tdb; 3095 1.42 dyoung return 0; 3096 1.42 dyoung } 3097 1.42 dyoung 3098 1.61 perry static inline struct mbuf * 3099 1.42 dyoung rtw_80211_dequeue(struct rtw_softc *sc, struct ifqueue *ifq, int pri, 3100 1.42 dyoung struct rtw_txsoft_blk **tsbp, struct rtw_txdesc_blk **tdbp, 3101 1.42 dyoung struct ieee80211_node **nip, short *if_flagsp) 3102 1.42 dyoung { 3103 1.42 dyoung struct mbuf *m; 3104 1.42 dyoung 3105 1.42 dyoung if (IF_IS_EMPTY(ifq)) 3106 1.42 dyoung return NULL; 3107 1.42 dyoung if (rtw_txring_choose(sc, tsbp, tdbp, pri) == -1) { 3108 1.58 dyoung DPRINTF(sc, RTW_DEBUG_XMIT_RSRC, ("%s: no ring %d descriptor\n", 3109 1.58 dyoung __func__, pri)); 3110 1.42 dyoung *if_flagsp |= IFF_OACTIVE; 3111 1.58 dyoung sc->sc_if.if_timer = 1; 3112 1.42 dyoung return NULL; 3113 1.42 dyoung } 3114 1.42 dyoung IF_DEQUEUE(ifq, m); 3115 1.122 ozaki *nip = M_GETCTX(m, struct ieee80211_node *); 3116 1.122 ozaki M_SETCTX(m, NULL); 3117 1.48 dyoung KASSERT(*nip != NULL); 3118 1.42 dyoung return m; 3119 1.42 dyoung } 3120 1.42 dyoung 3121 1.34 dyoung /* Point *mp at the next 802.11 frame to transmit. Point *tsbp 3122 1.1 dyoung * at the driver's selection of transmit control block for the packet. 3123 1.1 dyoung */ 3124 1.61 perry static inline int 3125 1.34 dyoung rtw_dequeue(struct ifnet *ifp, struct rtw_txsoft_blk **tsbp, 3126 1.34 dyoung struct rtw_txdesc_blk **tdbp, struct mbuf **mp, 3127 1.1 dyoung struct ieee80211_node **nip) 3128 1.1 dyoung { 3129 1.48 dyoung int pri; 3130 1.48 dyoung struct ether_header *eh; 3131 1.1 dyoung struct mbuf *m0; 3132 1.1 dyoung struct rtw_softc *sc; 3133 1.42 dyoung short *if_flagsp; 3134 1.1 dyoung 3135 1.84 dyoung *mp = NULL; 3136 1.84 dyoung 3137 1.1 dyoung sc = (struct rtw_softc *)ifp->if_softc; 3138 1.1 dyoung 3139 1.21 dyoung DPRINTF(sc, RTW_DEBUG_XMIT, 3140 1.98 dyoung ("%s: enter %s\n", device_xname(sc->sc_dev), __func__)); 3141 1.1 dyoung 3142 1.42 dyoung if_flagsp = &ifp->if_flags; 3143 1.5 dyoung 3144 1.42 dyoung if (sc->sc_ic.ic_state == IEEE80211_S_RUN && 3145 1.42 dyoung (*mp = rtw_80211_dequeue(sc, &sc->sc_beaconq, RTW_TXPRIBCN, tsbp, 3146 1.132 msaitoh tdbp, nip, if_flagsp)) != NULL) { 3147 1.42 dyoung DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue beacon frame\n", 3148 1.42 dyoung __func__)); 3149 1.5 dyoung return 0; 3150 1.5 dyoung } 3151 1.5 dyoung 3152 1.42 dyoung if ((*mp = rtw_80211_dequeue(sc, &sc->sc_ic.ic_mgtq, RTW_TXPRIMD, tsbp, 3153 1.132 msaitoh tdbp, nip, if_flagsp)) != NULL) { 3154 1.42 dyoung DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue mgt frame\n", 3155 1.42 dyoung __func__)); 3156 1.42 dyoung return 0; 3157 1.42 dyoung } 3158 1.5 dyoung 3159 1.42 dyoung if (sc->sc_ic.ic_state != IEEE80211_S_RUN) { 3160 1.21 dyoung DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__)); 3161 1.1 dyoung return 0; 3162 1.42 dyoung } 3163 1.42 dyoung 3164 1.48 dyoung IFQ_POLL(&ifp->if_snd, m0); 3165 1.48 dyoung if (m0 == NULL) { 3166 1.48 dyoung DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame ready\n", 3167 1.42 dyoung __func__)); 3168 1.42 dyoung return 0; 3169 1.42 dyoung } 3170 1.42 dyoung 3171 1.48 dyoung pri = ((m0->m_flags & M_PWR_SAV) != 0) ? RTW_TXPRIHI : RTW_TXPRIMD; 3172 1.48 dyoung 3173 1.48 dyoung if (rtw_txring_choose(sc, tsbp, tdbp, pri) == -1) { 3174 1.58 dyoung DPRINTF(sc, RTW_DEBUG_XMIT_RSRC, ("%s: no ring %d descriptor\n", 3175 1.58 dyoung __func__, pri)); 3176 1.42 dyoung *if_flagsp |= IFF_OACTIVE; 3177 1.58 dyoung sc->sc_if.if_timer = 1; 3178 1.42 dyoung return 0; 3179 1.42 dyoung } 3180 1.42 dyoung 3181 1.42 dyoung IFQ_DEQUEUE(&ifp->if_snd, m0); 3182 1.42 dyoung if (m0 == NULL) { 3183 1.48 dyoung DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame ready\n", 3184 1.42 dyoung __func__)); 3185 1.42 dyoung return 0; 3186 1.42 dyoung } 3187 1.42 dyoung DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue data frame\n", __func__)); 3188 1.135 thorpej if_statinc(ifp, if_opackets); 3189 1.128 msaitoh bpf_mtap(ifp, m0, BPF_D_OUT); 3190 1.48 dyoung eh = mtod(m0, struct ether_header *); 3191 1.48 dyoung *nip = ieee80211_find_txnode(&sc->sc_ic, eh->ether_dhost); 3192 1.48 dyoung if (*nip == NULL) { 3193 1.48 dyoung /* NB: ieee80211_find_txnode does stat+msg */ 3194 1.48 dyoung m_freem(m0); 3195 1.48 dyoung return -1; 3196 1.48 dyoung } 3197 1.48 dyoung if ((m0 = ieee80211_encap(&sc->sc_ic, m0, *nip)) == NULL) { 3198 1.48 dyoung DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: encap error\n", __func__)); 3199 1.135 thorpej if_statinc(ifp, if_oerrors); 3200 1.42 dyoung return -1; 3201 1.1 dyoung } 3202 1.21 dyoung DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__)); 3203 1.1 dyoung *mp = m0; 3204 1.1 dyoung return 0; 3205 1.1 dyoung } 3206 1.1 dyoung 3207 1.21 dyoung static int 3208 1.21 dyoung rtw_seg_too_short(bus_dmamap_t dmamap) 3209 1.21 dyoung { 3210 1.21 dyoung int i; 3211 1.21 dyoung for (i = 0; i < dmamap->dm_nsegs; i++) { 3212 1.83 dyoung if (dmamap->dm_segs[i].ds_len < 4) 3213 1.21 dyoung return 1; 3214 1.21 dyoung } 3215 1.21 dyoung return 0; 3216 1.21 dyoung } 3217 1.21 dyoung 3218 1.5 dyoung /* TBD factor with atw_start */ 3219 1.5 dyoung static struct mbuf * 3220 1.5 dyoung rtw_dmamap_load_txbuf(bus_dma_tag_t dmat, bus_dmamap_t dmam, struct mbuf *chain, 3221 1.98 dyoung u_int ndescfree, device_t dev) 3222 1.5 dyoung { 3223 1.5 dyoung int first, rc; 3224 1.5 dyoung struct mbuf *m, *m0; 3225 1.5 dyoung 3226 1.5 dyoung m0 = chain; 3227 1.5 dyoung 3228 1.5 dyoung /* 3229 1.5 dyoung * Load the DMA map. Copy and try (once) again if the packet 3230 1.5 dyoung * didn't fit in the alloted number of segments. 3231 1.5 dyoung */ 3232 1.5 dyoung for (first = 1; 3233 1.5 dyoung ((rc = bus_dmamap_load_mbuf(dmat, dmam, m0, 3234 1.131 msaitoh BUS_DMA_WRITE | BUS_DMA_NOWAIT)) != 0 || 3235 1.21 dyoung dmam->dm_nsegs > ndescfree || rtw_seg_too_short(dmam)) && first; 3236 1.5 dyoung first = 0) { 3237 1.83 dyoung if (rc == 0) { 3238 1.83 dyoung #ifdef RTW_DIAGxxx 3239 1.83 dyoung if (rtw_seg_too_short(dmam)) { 3240 1.83 dyoung printf("%s: short segment, mbuf lengths:", __func__); 3241 1.83 dyoung for (m = m0; m; m = m->m_next) 3242 1.83 dyoung printf(" %d", m->m_len); 3243 1.83 dyoung printf("\n"); 3244 1.83 dyoung } 3245 1.83 dyoung #endif 3246 1.5 dyoung bus_dmamap_unload(dmat, dmam); 3247 1.83 dyoung } 3248 1.5 dyoung MGETHDR(m, M_DONTWAIT, MT_DATA); 3249 1.5 dyoung if (m == NULL) { 3250 1.98 dyoung aprint_error_dev(dev, "unable to allocate Tx mbuf\n"); 3251 1.5 dyoung break; 3252 1.5 dyoung } 3253 1.5 dyoung if (m0->m_pkthdr.len > MHLEN) { 3254 1.5 dyoung MCLGET(m, M_DONTWAIT); 3255 1.5 dyoung if ((m->m_flags & M_EXT) == 0) { 3256 1.98 dyoung aprint_error_dev(dev, 3257 1.98 dyoung "cannot allocate Tx cluster\n"); 3258 1.5 dyoung m_freem(m); 3259 1.5 dyoung break; 3260 1.5 dyoung } 3261 1.5 dyoung } 3262 1.85 christos m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, void *)); 3263 1.5 dyoung m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len; 3264 1.5 dyoung m_freem(m0); 3265 1.5 dyoung m0 = m; 3266 1.5 dyoung m = NULL; 3267 1.5 dyoung } 3268 1.5 dyoung if (rc != 0) { 3269 1.98 dyoung aprint_error_dev(dev, "cannot load Tx buffer, rc = %d\n", rc); 3270 1.5 dyoung m_freem(m0); 3271 1.5 dyoung return NULL; 3272 1.21 dyoung } else if (rtw_seg_too_short(dmam)) { 3273 1.98 dyoung aprint_error_dev(dev, 3274 1.98 dyoung "cannot load Tx buffer, segment too short\n"); 3275 1.21 dyoung bus_dmamap_unload(dmat, dmam); 3276 1.21 dyoung m_freem(m0); 3277 1.21 dyoung return NULL; 3278 1.5 dyoung } else if (dmam->dm_nsegs > ndescfree) { 3279 1.98 dyoung aprint_error_dev(dev, "too many tx segments\n"); 3280 1.5 dyoung bus_dmamap_unload(dmat, dmam); 3281 1.5 dyoung m_freem(m0); 3282 1.5 dyoung return NULL; 3283 1.5 dyoung } 3284 1.5 dyoung return m0; 3285 1.5 dyoung } 3286 1.5 dyoung 3287 1.21 dyoung #ifdef RTW_DEBUG 3288 1.1 dyoung static void 3289 1.16 dyoung rtw_print_txdesc(struct rtw_softc *sc, const char *action, 3290 1.34 dyoung struct rtw_txsoft *ts, struct rtw_txdesc_blk *tdb, int desc) 3291 1.16 dyoung { 3292 1.34 dyoung struct rtw_txdesc *td = &tdb->tdb_desc[desc]; 3293 1.58 dyoung DPRINTF(sc, RTW_DEBUG_XMIT_DESC, ("%s: %p %s txdesc[%d] next %#08x " 3294 1.58 dyoung "buf %#08x ctl0 %#08x ctl1 %#08x len %#08x\n", 3295 1.98 dyoung device_xname(sc->sc_dev), ts, action, desc, 3296 1.58 dyoung le32toh(td->td_buf), le32toh(td->td_next), 3297 1.58 dyoung le32toh(td->td_ctl0), le32toh(td->td_ctl1), 3298 1.34 dyoung le32toh(td->td_len))); 3299 1.16 dyoung } 3300 1.21 dyoung #endif /* RTW_DEBUG */ 3301 1.16 dyoung 3302 1.16 dyoung static void 3303 1.1 dyoung rtw_start(struct ifnet *ifp) 3304 1.1 dyoung { 3305 1.5 dyoung int desc, i, lastdesc, npkt, rate; 3306 1.14 dyoung uint32_t proto_ctl0, ctl0, ctl1; 3307 1.5 dyoung bus_dmamap_t dmamap; 3308 1.5 dyoung struct ieee80211com *ic; 3309 1.5 dyoung struct ieee80211_duration *d0; 3310 1.49 dyoung struct ieee80211_frame_min *wh; 3311 1.73 christos struct ieee80211_node *ni = NULL; /* XXX: GCC */ 3312 1.5 dyoung struct mbuf *m0; 3313 1.5 dyoung struct rtw_softc *sc; 3314 1.73 christos struct rtw_txsoft_blk *tsb = NULL; /* XXX: GCC */ 3315 1.73 christos struct rtw_txdesc_blk *tdb = NULL; /* XXX: GCC */ 3316 1.34 dyoung struct rtw_txsoft *ts; 3317 1.34 dyoung struct rtw_txdesc *td; 3318 1.49 dyoung struct ieee80211_key *k; 3319 1.1 dyoung 3320 1.1 dyoung sc = (struct rtw_softc *)ifp->if_softc; 3321 1.5 dyoung ic = &sc->sc_ic; 3322 1.1 dyoung 3323 1.21 dyoung DPRINTF(sc, RTW_DEBUG_XMIT, 3324 1.98 dyoung ("%s: enter %s\n", device_xname(sc->sc_dev), __func__)); 3325 1.5 dyoung 3326 1.131 msaitoh if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 3327 1.31 dyoung goto out; 3328 1.31 dyoung 3329 1.5 dyoung /* XXX do real rate control */ 3330 1.14 dyoung proto_ctl0 = RTW_TXCTL0_RTSRATE_1MBPS; 3331 1.5 dyoung 3332 1.5 dyoung if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0) 3333 1.14 dyoung proto_ctl0 |= RTW_TXCTL0_SPLCP; 3334 1.5 dyoung 3335 1.5 dyoung for (;;) { 3336 1.34 dyoung if (rtw_dequeue(ifp, &tsb, &tdb, &m0, &ni) == -1) 3337 1.1 dyoung continue; 3338 1.1 dyoung if (m0 == NULL) 3339 1.1 dyoung break; 3340 1.49 dyoung 3341 1.49 dyoung wh = mtod(m0, struct ieee80211_frame_min *); 3342 1.49 dyoung 3343 1.49 dyoung if ((wh->i_fc[1] & IEEE80211_FC1_WEP) != 0 && 3344 1.49 dyoung (k = ieee80211_crypto_encap(ic, ni, m0)) == NULL) { 3345 1.51 dyoung m_freem(m0); 3346 1.49 dyoung break; 3347 1.49 dyoung } else 3348 1.49 dyoung k = NULL; 3349 1.49 dyoung 3350 1.34 dyoung ts = SIMPLEQ_FIRST(&tsb->tsb_freeq); 3351 1.5 dyoung 3352 1.34 dyoung dmamap = ts->ts_dmamap; 3353 1.5 dyoung 3354 1.5 dyoung m0 = rtw_dmamap_load_txbuf(sc->sc_dmat, dmamap, m0, 3355 1.98 dyoung tdb->tdb_nfree, sc->sc_dev); 3356 1.5 dyoung 3357 1.5 dyoung if (m0 == NULL || dmamap->dm_nsegs == 0) { 3358 1.21 dyoung DPRINTF(sc, RTW_DEBUG_XMIT, 3359 1.21 dyoung ("%s: fail dmamap load\n", __func__)); 3360 1.5 dyoung goto post_dequeue_err; 3361 1.5 dyoung } 3362 1.5 dyoung 3363 1.49 dyoung /* Note well: rtw_dmamap_load_txbuf may have created 3364 1.49 dyoung * a new chain, so we must find the header once 3365 1.49 dyoung * more. 3366 1.49 dyoung */ 3367 1.49 dyoung wh = mtod(m0, struct ieee80211_frame_min *); 3368 1.45 dyoung 3369 1.45 dyoung /* XXX do real rate control */ 3370 1.45 dyoung if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 3371 1.45 dyoung IEEE80211_FC0_TYPE_MGT) 3372 1.45 dyoung rate = 2; 3373 1.45 dyoung else 3374 1.72 dyoung rate = MAX(2, ieee80211_get_rate(ni)); 3375 1.45 dyoung 3376 1.16 dyoung #ifdef RTW_DEBUG 3377 1.131 msaitoh if ((ifp->if_flags & (IFF_DEBUG | IFF_LINK2)) == 3378 1.131 msaitoh (IFF_DEBUG | IFF_LINK2)) { 3379 1.16 dyoung ieee80211_dump_pkt(mtod(m0, uint8_t *), 3380 1.16 dyoung (dmamap->dm_nsegs == 1) ? m0->m_pkthdr.len 3381 1.132 msaitoh : sizeof(wh), 3382 1.16 dyoung rate, 0); 3383 1.16 dyoung } 3384 1.16 dyoung #endif /* RTW_DEBUG */ 3385 1.14 dyoung ctl0 = proto_ctl0 | 3386 1.75 dyoung __SHIFTIN(m0->m_pkthdr.len, RTW_TXCTL0_TPKTSIZE_MASK); 3387 1.5 dyoung 3388 1.45 dyoung switch (rate) { 3389 1.42 dyoung default: 3390 1.42 dyoung case 2: 3391 1.42 dyoung ctl0 |= RTW_TXCTL0_RATE_1MBPS; 3392 1.42 dyoung break; 3393 1.42 dyoung case 4: 3394 1.42 dyoung ctl0 |= RTW_TXCTL0_RATE_2MBPS; 3395 1.42 dyoung break; 3396 1.42 dyoung case 11: 3397 1.42 dyoung ctl0 |= RTW_TXCTL0_RATE_5MBPS; 3398 1.42 dyoung break; 3399 1.42 dyoung case 22: 3400 1.42 dyoung ctl0 |= RTW_TXCTL0_RATE_11MBPS; 3401 1.42 dyoung break; 3402 1.42 dyoung } 3403 1.45 dyoung /* XXX >= ? Compare after fragmentation? */ 3404 1.45 dyoung if (m0->m_pkthdr.len > ic->ic_rtsthreshold) 3405 1.45 dyoung ctl0 |= RTW_TXCTL0_RTSEN; 3406 1.45 dyoung 3407 1.132 msaitoh /* XXX Sometimes writes a bogus keyid; h/w doesn't 3408 1.132 msaitoh * seem to care, since we don't activate h/w Tx 3409 1.132 msaitoh * encryption. 3410 1.66 dyoung */ 3411 1.107 dyoung if (k != NULL && 3412 1.107 dyoung k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP) { 3413 1.75 dyoung ctl0 |= __SHIFTIN(k->wk_keyix, RTW_TXCTL0_KEYID_MASK) & 3414 1.49 dyoung RTW_TXCTL0_KEYID_MASK; 3415 1.49 dyoung } 3416 1.42 dyoung 3417 1.45 dyoung if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 3418 1.45 dyoung IEEE80211_FC0_TYPE_MGT) { 3419 1.45 dyoung ctl0 &= ~(RTW_TXCTL0_SPLCP | RTW_TXCTL0_RTSEN); 3420 1.45 dyoung if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == 3421 1.45 dyoung IEEE80211_FC0_SUBTYPE_BEACON) 3422 1.45 dyoung ctl0 |= RTW_TXCTL0_BEACON; 3423 1.45 dyoung } 3424 1.45 dyoung 3425 1.62 dyoung if (ieee80211_compute_duration(wh, k, m0->m_pkthdr.len, 3426 1.5 dyoung ic->ic_flags, ic->ic_fragthreshold, 3427 1.34 dyoung rate, &ts->ts_d0, &ts->ts_dn, &npkt, 3428 1.131 msaitoh (ifp->if_flags & (IFF_DEBUG | IFF_LINK2)) == 3429 1.131 msaitoh (IFF_DEBUG | IFF_LINK2)) == -1) { 3430 1.21 dyoung DPRINTF(sc, RTW_DEBUG_XMIT, 3431 1.21 dyoung ("%s: fail compute duration\n", __func__)); 3432 1.5 dyoung goto post_load_err; 3433 1.5 dyoung } 3434 1.5 dyoung 3435 1.34 dyoung d0 = &ts->ts_d0; 3436 1.5 dyoung 3437 1.20 dyoung *(uint16_t*)wh->i_dur = htole16(d0->d_data_dur); 3438 1.20 dyoung 3439 1.75 dyoung ctl1 = __SHIFTIN(d0->d_plcp_len, RTW_TXCTL1_LENGTH_MASK) | 3440 1.75 dyoung __SHIFTIN(d0->d_rts_dur, RTW_TXCTL1_RTSDUR_MASK); 3441 1.5 dyoung 3442 1.25 mycroft if (d0->d_residue) 3443 1.14 dyoung ctl1 |= RTW_TXCTL1_LENGEXT; 3444 1.5 dyoung 3445 1.5 dyoung /* TBD fragmentation */ 3446 1.5 dyoung 3447 1.34 dyoung ts->ts_first = tdb->tdb_next; 3448 1.5 dyoung 3449 1.34 dyoung rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs, 3450 1.5 dyoung BUS_DMASYNC_PREWRITE); 3451 1.5 dyoung 3452 1.34 dyoung KASSERT(ts->ts_first < tdb->tdb_ndesc); 3453 1.21 dyoung 3454 1.128 msaitoh bpf_mtap3(ic->ic_rawbpf, m0, BPF_D_OUT); 3455 1.32 dyoung 3456 1.32 dyoung if (sc->sc_radiobpf != NULL) { 3457 1.32 dyoung struct rtw_tx_radiotap_header *rt = &sc->sc_txtap; 3458 1.32 dyoung 3459 1.32 dyoung rt->rt_rate = rate; 3460 1.32 dyoung 3461 1.116 joerg bpf_mtap2(sc->sc_radiobpf, rt, sizeof(sc->sc_txtapu), 3462 1.128 msaitoh m0, BPF_D_OUT); 3463 1.32 dyoung } 3464 1.32 dyoung 3465 1.34 dyoung for (i = 0, lastdesc = desc = ts->ts_first; 3466 1.5 dyoung i < dmamap->dm_nsegs; 3467 1.34 dyoung i++, desc = RTW_NEXT_IDX(tdb, desc)) { 3468 1.5 dyoung if (dmamap->dm_segs[i].ds_len > RTW_TXLEN_LENGTH_MASK) { 3469 1.21 dyoung DPRINTF(sc, RTW_DEBUG_XMIT_DESC, 3470 1.21 dyoung ("%s: seg too long\n", __func__)); 3471 1.5 dyoung goto post_load_err; 3472 1.5 dyoung } 3473 1.34 dyoung td = &tdb->tdb_desc[desc]; 3474 1.34 dyoung td->td_ctl0 = htole32(ctl0); 3475 1.34 dyoung td->td_ctl1 = htole32(ctl1); 3476 1.34 dyoung td->td_buf = htole32(dmamap->dm_segs[i].ds_addr); 3477 1.34 dyoung td->td_len = htole32(dmamap->dm_segs[i].ds_len); 3478 1.92 dyoung td->td_next = htole32(RTW_NEXT_DESC(tdb, desc)); 3479 1.92 dyoung if (i != 0) 3480 1.92 dyoung td->td_ctl0 |= htole32(RTW_TXCTL0_OWN); 3481 1.5 dyoung lastdesc = desc; 3482 1.16 dyoung #ifdef RTW_DEBUG 3483 1.34 dyoung rtw_print_txdesc(sc, "load", ts, tdb, desc); 3484 1.16 dyoung #endif /* RTW_DEBUG */ 3485 1.5 dyoung } 3486 1.5 dyoung 3487 1.34 dyoung KASSERT(desc < tdb->tdb_ndesc); 3488 1.21 dyoung 3489 1.34 dyoung ts->ts_ni = ni; 3490 1.48 dyoung KASSERT(ni != NULL); 3491 1.34 dyoung ts->ts_mbuf = m0; 3492 1.34 dyoung ts->ts_last = lastdesc; 3493 1.34 dyoung tdb->tdb_desc[ts->ts_last].td_ctl0 |= htole32(RTW_TXCTL0_LS); 3494 1.34 dyoung tdb->tdb_desc[ts->ts_first].td_ctl0 |= 3495 1.5 dyoung htole32(RTW_TXCTL0_FS); 3496 1.5 dyoung 3497 1.16 dyoung #ifdef RTW_DEBUG 3498 1.34 dyoung rtw_print_txdesc(sc, "FS on", ts, tdb, ts->ts_first); 3499 1.34 dyoung rtw_print_txdesc(sc, "LS on", ts, tdb, ts->ts_last); 3500 1.16 dyoung #endif /* RTW_DEBUG */ 3501 1.5 dyoung 3502 1.34 dyoung tdb->tdb_nfree -= dmamap->dm_nsegs; 3503 1.34 dyoung tdb->tdb_next = desc; 3504 1.5 dyoung 3505 1.34 dyoung rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs, 3506 1.131 msaitoh BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 3507 1.5 dyoung 3508 1.34 dyoung tdb->tdb_desc[ts->ts_first].td_ctl0 |= 3509 1.5 dyoung htole32(RTW_TXCTL0_OWN); 3510 1.5 dyoung 3511 1.16 dyoung #ifdef RTW_DEBUG 3512 1.34 dyoung rtw_print_txdesc(sc, "OWN on", ts, tdb, ts->ts_first); 3513 1.16 dyoung #endif /* RTW_DEBUG */ 3514 1.5 dyoung 3515 1.34 dyoung rtw_txdescs_sync(tdb, ts->ts_first, 1, 3516 1.131 msaitoh BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 3517 1.5 dyoung 3518 1.34 dyoung SIMPLEQ_REMOVE_HEAD(&tsb->tsb_freeq, ts_q); 3519 1.34 dyoung SIMPLEQ_INSERT_TAIL(&tsb->tsb_dirtyq, ts, ts_q); 3520 1.5 dyoung 3521 1.58 dyoung if (tsb != &sc->sc_txsoft_blk[RTW_TXPRIBCN]) 3522 1.42 dyoung sc->sc_led_state.ls_event |= RTW_LED_S_TX; 3523 1.58 dyoung tsb->tsb_tx_timer = 5; 3524 1.58 dyoung ifp->if_timer = 1; 3525 1.103 dyoung rtw_tx_kick(&sc->sc_regs, tsb->tsb_poll); 3526 1.1 dyoung } 3527 1.31 dyoung out: 3528 1.21 dyoung DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__)); 3529 1.5 dyoung return; 3530 1.5 dyoung post_load_err: 3531 1.5 dyoung bus_dmamap_unload(sc->sc_dmat, dmamap); 3532 1.5 dyoung m_freem(m0); 3533 1.5 dyoung post_dequeue_err: 3534 1.48 dyoung ieee80211_free_node(ni); 3535 1.1 dyoung return; 3536 1.1 dyoung } 3537 1.1 dyoung 3538 1.1 dyoung static void 3539 1.58 dyoung rtw_idle(struct rtw_regs *regs) 3540 1.58 dyoung { 3541 1.58 dyoung int active; 3542 1.100 dyoung uint8_t tppoll; 3543 1.58 dyoung 3544 1.58 dyoung /* request stop DMA; wait for packets to stop transmitting. */ 3545 1.58 dyoung 3546 1.58 dyoung RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 3547 1.58 dyoung RTW_WBR(regs, RTW_TPPOLL, RTW_TPPOLL); 3548 1.58 dyoung 3549 1.58 dyoung for (active = 0; active < 300 && 3550 1.100 dyoung (tppoll = RTW_READ8(regs, RTW_TPPOLL) & RTW_TPPOLL_ACTIVE) != 0; 3551 1.100 dyoung active++) 3552 1.58 dyoung DELAY(10); 3553 1.100 dyoung printf("%s: transmit DMA idle in %dus, tppoll %02" PRIx8 "\n", __func__, 3554 1.100 dyoung active * 10, tppoll); 3555 1.58 dyoung } 3556 1.58 dyoung 3557 1.58 dyoung static void 3558 1.1 dyoung rtw_watchdog(struct ifnet *ifp) 3559 1.1 dyoung { 3560 1.58 dyoung int pri, tx_timeouts = 0; 3561 1.5 dyoung struct rtw_softc *sc; 3562 1.34 dyoung struct rtw_txsoft_blk *tsb; 3563 1.5 dyoung 3564 1.5 dyoung sc = ifp->if_softc; 3565 1.5 dyoung 3566 1.5 dyoung ifp->if_timer = 0; 3567 1.5 dyoung 3568 1.101 dyoung if (!device_is_active(sc->sc_dev)) 3569 1.5 dyoung return; 3570 1.5 dyoung 3571 1.5 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 3572 1.34 dyoung tsb = &sc->sc_txsoft_blk[pri]; 3573 1.5 dyoung 3574 1.34 dyoung if (tsb->tsb_tx_timer == 0) 3575 1.5 dyoung continue; 3576 1.58 dyoung else if (--tsb->tsb_tx_timer == 0) { 3577 1.34 dyoung if (SIMPLEQ_EMPTY(&tsb->tsb_dirtyq)) 3578 1.5 dyoung continue; 3579 1.107 dyoung else if (rtw_collect_txring(sc, tsb, 3580 1.107 dyoung &sc->sc_txdesc_blk[pri], 0)) 3581 1.107 dyoung continue; 3582 1.5 dyoung printf("%s: transmit timeout, priority %d\n", 3583 1.5 dyoung ifp->if_xname, pri); 3584 1.135 thorpej if_statinc(ifp, if_oerrors); 3585 1.83 dyoung if (pri != RTW_TXPRIBCN) 3586 1.83 dyoung tx_timeouts++; 3587 1.5 dyoung } else 3588 1.5 dyoung ifp->if_timer = 1; 3589 1.5 dyoung } 3590 1.58 dyoung 3591 1.58 dyoung if (tx_timeouts > 0) { 3592 1.58 dyoung /* Stop Tx DMA, disable xmtr, flush Tx rings, enable xmtr, 3593 1.58 dyoung * reset s/w tx-ring pointers, and start transmission. 3594 1.58 dyoung * 3595 1.58 dyoung * TBD Stop/restart just the broken rings? 3596 1.58 dyoung */ 3597 1.58 dyoung rtw_idle(&sc->sc_regs); 3598 1.107 dyoung rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0); 3599 1.58 dyoung rtw_txdescs_reset(sc); 3600 1.107 dyoung rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1); 3601 1.58 dyoung rtw_start(ifp); 3602 1.58 dyoung } 3603 1.48 dyoung ieee80211_watchdog(&sc->sc_ic); 3604 1.1 dyoung return; 3605 1.1 dyoung } 3606 1.1 dyoung 3607 1.1 dyoung static void 3608 1.1 dyoung rtw_next_scan(void *arg) 3609 1.1 dyoung { 3610 1.1 dyoung struct ieee80211com *ic = arg; 3611 1.1 dyoung int s; 3612 1.1 dyoung 3613 1.1 dyoung /* don't call rtw_start w/o network interrupts blocked */ 3614 1.1 dyoung s = splnet(); 3615 1.1 dyoung if (ic->ic_state == IEEE80211_S_SCAN) 3616 1.1 dyoung ieee80211_next_scan(ic); 3617 1.1 dyoung splx(s); 3618 1.1 dyoung } 3619 1.1 dyoung 3620 1.10 dyoung static void 3621 1.45 dyoung rtw_join_bss(struct rtw_softc *sc, uint8_t *bssid, uint16_t intval0) 3622 1.10 dyoung { 3623 1.58 dyoung uint16_t bcnitv, bintritv, intval; 3624 1.10 dyoung int i; 3625 1.10 dyoung struct rtw_regs *regs = &sc->sc_regs; 3626 1.10 dyoung 3627 1.10 dyoung for (i = 0; i < IEEE80211_ADDR_LEN; i++) 3628 1.10 dyoung RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]); 3629 1.10 dyoung 3630 1.10 dyoung RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32); 3631 1.10 dyoung 3632 1.42 dyoung rtw_set_access(regs, RTW_ACCESS_CONFIG); 3633 1.10 dyoung 3634 1.75 dyoung intval = MIN(intval0, __SHIFTOUT_MASK(RTW_BCNITV_BCNITV_MASK)); 3635 1.10 dyoung 3636 1.10 dyoung bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK; 3637 1.75 dyoung bcnitv |= __SHIFTIN(intval, RTW_BCNITV_BCNITV_MASK); 3638 1.10 dyoung RTW_WRITE16(regs, RTW_BCNITV, bcnitv); 3639 1.58 dyoung /* interrupt host 1ms before the TBTT */ 3640 1.58 dyoung bintritv = RTW_READ16(regs, RTW_BINTRITV) & ~RTW_BINTRITV_BINTRITV; 3641 1.75 dyoung bintritv |= __SHIFTIN(1000, RTW_BINTRITV_BINTRITV); 3642 1.58 dyoung RTW_WRITE16(regs, RTW_BINTRITV, bintritv); 3643 1.10 dyoung /* magic from Linux */ 3644 1.75 dyoung RTW_WRITE16(regs, RTW_ATIMWND, __SHIFTIN(1, RTW_ATIMWND_ATIMWND)); 3645 1.75 dyoung RTW_WRITE16(regs, RTW_ATIMTRITV, __SHIFTIN(2, RTW_ATIMTRITV_ATIMTRITV)); 3646 1.42 dyoung rtw_set_access(regs, RTW_ACCESS_NONE); 3647 1.10 dyoung 3648 1.83 dyoung rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1); 3649 1.10 dyoung } 3650 1.10 dyoung 3651 1.1 dyoung /* Synchronize the hardware state with the software state. */ 3652 1.1 dyoung static int 3653 1.1 dyoung rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 3654 1.1 dyoung { 3655 1.48 dyoung struct ifnet *ifp = ic->ic_ifp; 3656 1.48 dyoung struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 3657 1.1 dyoung enum ieee80211_state ostate; 3658 1.1 dyoung int error; 3659 1.1 dyoung 3660 1.1 dyoung ostate = ic->ic_state; 3661 1.1 dyoung 3662 1.101 dyoung aprint_debug_dev(sc->sc_dev, "%s: l.%d\n", __func__, __LINE__); 3663 1.42 dyoung rtw_led_newstate(sc, nstate); 3664 1.42 dyoung 3665 1.101 dyoung aprint_debug_dev(sc->sc_dev, "%s: l.%d\n", __func__, __LINE__); 3666 1.1 dyoung if (nstate == IEEE80211_S_INIT) { 3667 1.1 dyoung callout_stop(&sc->sc_scan_ch); 3668 1.1 dyoung sc->sc_cur_chan = IEEE80211_CHAN_ANY; 3669 1.1 dyoung return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg); 3670 1.1 dyoung } 3671 1.1 dyoung 3672 1.1 dyoung if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT) 3673 1.1 dyoung rtw_pwrstate(sc, RTW_ON); 3674 1.1 dyoung 3675 1.1 dyoung if ((error = rtw_tune(sc)) != 0) 3676 1.1 dyoung return error; 3677 1.1 dyoung 3678 1.1 dyoung switch (nstate) { 3679 1.1 dyoung case IEEE80211_S_INIT: 3680 1.1 dyoung panic("%s: unexpected state IEEE80211_S_INIT\n", __func__); 3681 1.1 dyoung break; 3682 1.1 dyoung case IEEE80211_S_SCAN: 3683 1.21 dyoung if (ostate != IEEE80211_S_SCAN) { 3684 1.21 dyoung (void)memset(ic->ic_bss->ni_bssid, 0, 3685 1.21 dyoung IEEE80211_ADDR_LEN); 3686 1.45 dyoung rtw_set_nettype(sc, IEEE80211_M_MONITOR); 3687 1.21 dyoung } 3688 1.1 dyoung 3689 1.1 dyoung callout_reset(&sc->sc_scan_ch, rtw_dwelltime * hz / 1000, 3690 1.1 dyoung rtw_next_scan, ic); 3691 1.1 dyoung 3692 1.1 dyoung break; 3693 1.1 dyoung case IEEE80211_S_RUN: 3694 1.38 dyoung switch (ic->ic_opmode) { 3695 1.38 dyoung case IEEE80211_M_HOSTAP: 3696 1.38 dyoung case IEEE80211_M_IBSS: 3697 1.45 dyoung rtw_set_nettype(sc, IEEE80211_M_MONITOR); 3698 1.42 dyoung /*FALLTHROUGH*/ 3699 1.42 dyoung case IEEE80211_M_AHDEMO: 3700 1.45 dyoung case IEEE80211_M_STA: 3701 1.45 dyoung rtw_join_bss(sc, ic->ic_bss->ni_bssid, 3702 1.38 dyoung ic->ic_bss->ni_intval); 3703 1.1 dyoung break; 3704 1.38 dyoung case IEEE80211_M_MONITOR: 3705 1.38 dyoung break; 3706 1.38 dyoung } 3707 1.45 dyoung rtw_set_nettype(sc, ic->ic_opmode); 3708 1.38 dyoung break; 3709 1.45 dyoung case IEEE80211_S_ASSOC: 3710 1.1 dyoung case IEEE80211_S_AUTH: 3711 1.1 dyoung break; 3712 1.1 dyoung } 3713 1.1 dyoung 3714 1.1 dyoung if (nstate != IEEE80211_S_SCAN) 3715 1.1 dyoung callout_stop(&sc->sc_scan_ch); 3716 1.1 dyoung 3717 1.1 dyoung return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg); 3718 1.1 dyoung } 3719 1.1 dyoung 3720 1.40 dyoung /* Extend a 32-bit TSF timestamp to a 64-bit timestamp. */ 3721 1.40 dyoung static uint64_t 3722 1.40 dyoung rtw_tsf_extend(struct rtw_regs *regs, uint32_t rstamp) 3723 1.40 dyoung { 3724 1.40 dyoung uint32_t tsftl, tsfth; 3725 1.40 dyoung 3726 1.40 dyoung tsfth = RTW_READ(regs, RTW_TSFTRH); 3727 1.40 dyoung tsftl = RTW_READ(regs, RTW_TSFTRL); 3728 1.40 dyoung if (tsftl < rstamp) /* Compensate for rollover. */ 3729 1.40 dyoung tsfth--; 3730 1.40 dyoung return ((uint64_t)tsfth << 32) | rstamp; 3731 1.40 dyoung } 3732 1.40 dyoung 3733 1.1 dyoung static void 3734 1.1 dyoung rtw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m, 3735 1.37 dyoung struct ieee80211_node *ni, int subtype, int rssi, uint32_t rstamp) 3736 1.1 dyoung { 3737 1.48 dyoung struct ifnet *ifp = ic->ic_ifp; 3738 1.48 dyoung struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 3739 1.1 dyoung 3740 1.40 dyoung (*sc->sc_mtbl.mt_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp); 3741 1.40 dyoung 3742 1.1 dyoung switch (subtype) { 3743 1.1 dyoung case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 3744 1.1 dyoung case IEEE80211_FC0_SUBTYPE_BEACON: 3745 1.63 dyoung if (ic->ic_opmode == IEEE80211_M_IBSS && 3746 1.101 dyoung ic->ic_state == IEEE80211_S_RUN && 3747 1.101 dyoung device_is_active(sc->sc_dev)) { 3748 1.63 dyoung uint64_t tsf = rtw_tsf_extend(&sc->sc_regs, rstamp); 3749 1.63 dyoung if (le64toh(ni->ni_tstamp.tsf) >= tsf) 3750 1.63 dyoung (void)ieee80211_ibss_merge(ni); 3751 1.63 dyoung } 3752 1.1 dyoung break; 3753 1.1 dyoung default: 3754 1.1 dyoung break; 3755 1.1 dyoung } 3756 1.1 dyoung return; 3757 1.1 dyoung } 3758 1.1 dyoung 3759 1.1 dyoung static struct ieee80211_node * 3760 1.48 dyoung rtw_node_alloc(struct ieee80211_node_table *nt) 3761 1.1 dyoung { 3762 1.48 dyoung struct ifnet *ifp = nt->nt_ic->ic_ifp; 3763 1.48 dyoung struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 3764 1.48 dyoung struct ieee80211_node *ni = (*sc->sc_mtbl.mt_node_alloc)(nt); 3765 1.1 dyoung 3766 1.21 dyoung DPRINTF(sc, RTW_DEBUG_NODE, 3767 1.98 dyoung ("%s: alloc node %p\n", device_xname(sc->sc_dev), ni)); 3768 1.1 dyoung return ni; 3769 1.1 dyoung } 3770 1.1 dyoung 3771 1.1 dyoung static void 3772 1.48 dyoung rtw_node_free(struct ieee80211_node *ni) 3773 1.1 dyoung { 3774 1.48 dyoung struct ieee80211com *ic = ni->ni_ic; 3775 1.48 dyoung struct ifnet *ifp = ic->ic_ifp; 3776 1.48 dyoung struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 3777 1.1 dyoung 3778 1.21 dyoung DPRINTF(sc, RTW_DEBUG_NODE, 3779 1.98 dyoung ("%s: freeing node %p %s\n", device_xname(sc->sc_dev), ni, 3780 1.1 dyoung ether_sprintf(ni->ni_bssid))); 3781 1.48 dyoung (*sc->sc_mtbl.mt_node_free)(ni); 3782 1.1 dyoung } 3783 1.1 dyoung 3784 1.1 dyoung static int 3785 1.1 dyoung rtw_media_change(struct ifnet *ifp) 3786 1.1 dyoung { 3787 1.1 dyoung int error; 3788 1.1 dyoung 3789 1.1 dyoung error = ieee80211_media_change(ifp); 3790 1.1 dyoung if (error == ENETRESET) { 3791 1.131 msaitoh if ((ifp->if_flags & (IFF_RUNNING | IFF_UP)) == 3792 1.131 msaitoh (IFF_RUNNING | IFF_UP)) 3793 1.1 dyoung rtw_init(ifp); /* XXX lose error */ 3794 1.1 dyoung error = 0; 3795 1.1 dyoung } 3796 1.1 dyoung return error; 3797 1.1 dyoung } 3798 1.1 dyoung 3799 1.1 dyoung static void 3800 1.1 dyoung rtw_media_status(struct ifnet *ifp, struct ifmediareq *imr) 3801 1.1 dyoung { 3802 1.1 dyoung struct rtw_softc *sc = ifp->if_softc; 3803 1.1 dyoung 3804 1.101 dyoung if (!device_is_active(sc->sc_dev)) { 3805 1.1 dyoung imr->ifm_active = IFM_IEEE80211 | IFM_NONE; 3806 1.1 dyoung imr->ifm_status = 0; 3807 1.1 dyoung return; 3808 1.1 dyoung } 3809 1.1 dyoung ieee80211_media_status(ifp, imr); 3810 1.1 dyoung } 3811 1.1 dyoung 3812 1.61 perry static inline void 3813 1.7 dyoung rtw_setifprops(struct ifnet *ifp, const char *dvname, void *softc) 3814 1.1 dyoung { 3815 1.98 dyoung (void)strlcpy(ifp->if_xname, dvname, IFNAMSIZ); 3816 1.1 dyoung ifp->if_softc = softc; 3817 1.130 msaitoh ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 3818 1.1 dyoung ifp->if_ioctl = rtw_ioctl; 3819 1.1 dyoung ifp->if_start = rtw_start; 3820 1.1 dyoung ifp->if_watchdog = rtw_watchdog; 3821 1.1 dyoung ifp->if_init = rtw_init; 3822 1.1 dyoung ifp->if_stop = rtw_stop; 3823 1.1 dyoung } 3824 1.1 dyoung 3825 1.61 perry static inline void 3826 1.1 dyoung rtw_set80211props(struct ieee80211com *ic) 3827 1.1 dyoung { 3828 1.1 dyoung int nrate; 3829 1.1 dyoung ic->ic_phytype = IEEE80211_T_DS; 3830 1.1 dyoung ic->ic_opmode = IEEE80211_M_STA; 3831 1.1 dyoung ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS | 3832 1.107 dyoung IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP; 3833 1.1 dyoung 3834 1.1 dyoung nrate = 0; 3835 1.12 dyoung ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 3836 1.12 dyoung IEEE80211_RATE_BASIC | 2; 3837 1.12 dyoung ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 3838 1.12 dyoung IEEE80211_RATE_BASIC | 4; 3839 1.1 dyoung ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 11; 3840 1.1 dyoung ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 22; 3841 1.1 dyoung ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate; 3842 1.1 dyoung } 3843 1.1 dyoung 3844 1.61 perry static inline void 3845 1.1 dyoung rtw_set80211methods(struct rtw_mtbl *mtbl, struct ieee80211com *ic) 3846 1.1 dyoung { 3847 1.1 dyoung mtbl->mt_newstate = ic->ic_newstate; 3848 1.1 dyoung ic->ic_newstate = rtw_newstate; 3849 1.1 dyoung 3850 1.1 dyoung mtbl->mt_recv_mgmt = ic->ic_recv_mgmt; 3851 1.1 dyoung ic->ic_recv_mgmt = rtw_recv_mgmt; 3852 1.1 dyoung 3853 1.1 dyoung mtbl->mt_node_free = ic->ic_node_free; 3854 1.1 dyoung ic->ic_node_free = rtw_node_free; 3855 1.1 dyoung 3856 1.1 dyoung mtbl->mt_node_alloc = ic->ic_node_alloc; 3857 1.1 dyoung ic->ic_node_alloc = rtw_node_alloc; 3858 1.49 dyoung 3859 1.49 dyoung ic->ic_crypto.cs_key_delete = rtw_key_delete; 3860 1.49 dyoung ic->ic_crypto.cs_key_set = rtw_key_set; 3861 1.49 dyoung ic->ic_crypto.cs_key_update_begin = rtw_key_update_begin; 3862 1.49 dyoung ic->ic_crypto.cs_key_update_end = rtw_key_update_end; 3863 1.1 dyoung } 3864 1.1 dyoung 3865 1.61 perry static inline void 3866 1.1 dyoung rtw_init_radiotap(struct rtw_softc *sc) 3867 1.1 dyoung { 3868 1.93 dyoung uint32_t present; 3869 1.93 dyoung 3870 1.1 dyoung memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu)); 3871 1.32 dyoung sc->sc_rxtap.rr_ihdr.it_len = htole16(sizeof(sc->sc_rxtapu)); 3872 1.93 dyoung 3873 1.93 dyoung if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS) 3874 1.93 dyoung present = htole32(RTW_PHILIPS_RX_RADIOTAP_PRESENT); 3875 1.93 dyoung else 3876 1.93 dyoung present = htole32(RTW_RX_RADIOTAP_PRESENT); 3877 1.93 dyoung sc->sc_rxtap.rr_ihdr.it_present = present; 3878 1.1 dyoung 3879 1.1 dyoung memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu)); 3880 1.32 dyoung sc->sc_txtap.rt_ihdr.it_len = htole16(sizeof(sc->sc_txtapu)); 3881 1.32 dyoung sc->sc_txtap.rt_ihdr.it_present = htole32(RTW_TX_RADIOTAP_PRESENT); 3882 1.1 dyoung } 3883 1.1 dyoung 3884 1.1 dyoung static int 3885 1.34 dyoung rtw_txsoft_blk_setup(struct rtw_txsoft_blk *tsb, u_int qlen) 3886 1.1 dyoung { 3887 1.34 dyoung SIMPLEQ_INIT(&tsb->tsb_dirtyq); 3888 1.34 dyoung SIMPLEQ_INIT(&tsb->tsb_freeq); 3889 1.34 dyoung tsb->tsb_ndesc = qlen; 3890 1.34 dyoung tsb->tsb_desc = malloc(qlen * sizeof(*tsb->tsb_desc), M_DEVBUF, 3891 1.134 chs M_WAITOK); 3892 1.1 dyoung return 0; 3893 1.1 dyoung } 3894 1.1 dyoung 3895 1.1 dyoung static void 3896 1.34 dyoung rtw_txsoft_blk_cleanup_all(struct rtw_softc *sc) 3897 1.1 dyoung { 3898 1.21 dyoung int pri; 3899 1.34 dyoung struct rtw_txsoft_blk *tsb; 3900 1.1 dyoung 3901 1.21 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 3902 1.34 dyoung tsb = &sc->sc_txsoft_blk[pri]; 3903 1.34 dyoung free(tsb->tsb_desc, M_DEVBUF); 3904 1.34 dyoung tsb->tsb_desc = NULL; 3905 1.1 dyoung } 3906 1.1 dyoung } 3907 1.1 dyoung 3908 1.1 dyoung static int 3909 1.34 dyoung rtw_txsoft_blk_setup_all(struct rtw_softc *sc) 3910 1.1 dyoung { 3911 1.1 dyoung int pri, rc = 0; 3912 1.1 dyoung int qlen[RTW_NTXPRI] = 3913 1.1 dyoung {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN}; 3914 1.42 dyoung struct rtw_txsoft_blk *tsbs; 3915 1.42 dyoung 3916 1.42 dyoung tsbs = sc->sc_txsoft_blk; 3917 1.1 dyoung 3918 1.21 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 3919 1.42 dyoung rc = rtw_txsoft_blk_setup(&tsbs[pri], qlen[pri]); 3920 1.1 dyoung if (rc != 0) 3921 1.1 dyoung break; 3922 1.1 dyoung } 3923 1.42 dyoung tsbs[RTW_TXPRILO].tsb_poll = RTW_TPPOLL_LPQ | RTW_TPPOLL_SLPQ; 3924 1.42 dyoung tsbs[RTW_TXPRIMD].tsb_poll = RTW_TPPOLL_NPQ | RTW_TPPOLL_SNPQ; 3925 1.42 dyoung tsbs[RTW_TXPRIHI].tsb_poll = RTW_TPPOLL_HPQ | RTW_TPPOLL_SHPQ; 3926 1.42 dyoung tsbs[RTW_TXPRIBCN].tsb_poll = RTW_TPPOLL_BQ | RTW_TPPOLL_SBQ; 3927 1.1 dyoung return rc; 3928 1.1 dyoung } 3929 1.1 dyoung 3930 1.1 dyoung static void 3931 1.34 dyoung rtw_txdesc_blk_setup(struct rtw_txdesc_blk *tdb, struct rtw_txdesc *desc, 3932 1.1 dyoung u_int ndesc, bus_addr_t ofs, bus_addr_t physbase) 3933 1.1 dyoung { 3934 1.34 dyoung tdb->tdb_ndesc = ndesc; 3935 1.34 dyoung tdb->tdb_desc = desc; 3936 1.34 dyoung tdb->tdb_physbase = physbase; 3937 1.34 dyoung tdb->tdb_ofs = ofs; 3938 1.1 dyoung 3939 1.34 dyoung (void)memset(tdb->tdb_desc, 0, 3940 1.34 dyoung sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc); 3941 1.1 dyoung 3942 1.58 dyoung rtw_txdesc_blk_init(tdb); 3943 1.58 dyoung tdb->tdb_next = 0; 3944 1.1 dyoung } 3945 1.1 dyoung 3946 1.1 dyoung static void 3947 1.1 dyoung rtw_txdesc_blk_setup_all(struct rtw_softc *sc) 3948 1.1 dyoung { 3949 1.1 dyoung rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRILO], 3950 1.1 dyoung &sc->sc_descs->hd_txlo[0], RTW_NTXDESCLO, 3951 1.1 dyoung RTW_RING_OFFSET(hd_txlo), RTW_RING_BASE(sc, hd_txlo)); 3952 1.1 dyoung 3953 1.1 dyoung rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIMD], 3954 1.1 dyoung &sc->sc_descs->hd_txmd[0], RTW_NTXDESCMD, 3955 1.1 dyoung RTW_RING_OFFSET(hd_txmd), RTW_RING_BASE(sc, hd_txmd)); 3956 1.1 dyoung 3957 1.1 dyoung rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIHI], 3958 1.1 dyoung &sc->sc_descs->hd_txhi[0], RTW_NTXDESCHI, 3959 1.1 dyoung RTW_RING_OFFSET(hd_txhi), RTW_RING_BASE(sc, hd_txhi)); 3960 1.1 dyoung 3961 1.1 dyoung rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIBCN], 3962 1.1 dyoung &sc->sc_descs->hd_bcn[0], RTW_NTXDESCBCN, 3963 1.1 dyoung RTW_RING_OFFSET(hd_bcn), RTW_RING_BASE(sc, hd_bcn)); 3964 1.1 dyoung } 3965 1.1 dyoung 3966 1.1 dyoung static struct rtw_rf * 3967 1.42 dyoung rtw_rf_attach(struct rtw_softc *sc, enum rtw_rfchipid rfchipid, int digphy) 3968 1.1 dyoung { 3969 1.42 dyoung rtw_rf_write_t rf_write; 3970 1.1 dyoung struct rtw_rf *rf; 3971 1.1 dyoung 3972 1.1 dyoung switch (rfchipid) { 3973 1.42 dyoung default: 3974 1.42 dyoung rf_write = rtw_rf_hostwrite; 3975 1.42 dyoung break; 3976 1.42 dyoung case RTW_RFCHIPID_INTERSIL: 3977 1.42 dyoung case RTW_RFCHIPID_PHILIPS: 3978 1.42 dyoung case RTW_RFCHIPID_GCT: /* XXX a guess */ 3979 1.42 dyoung case RTW_RFCHIPID_RFMD: 3980 1.42 dyoung rf_write = (rtw_host_rfio) ? rtw_rf_hostwrite : rtw_rf_macwrite; 3981 1.42 dyoung break; 3982 1.42 dyoung } 3983 1.42 dyoung 3984 1.42 dyoung switch (rfchipid) { 3985 1.64 dyoung case RTW_RFCHIPID_GCT: 3986 1.64 dyoung rf = rtw_grf5101_create(&sc->sc_regs, rf_write, 0); 3987 1.64 dyoung sc->sc_pwrstate_cb = rtw_maxim_pwrstate; 3988 1.64 dyoung break; 3989 1.1 dyoung case RTW_RFCHIPID_MAXIM: 3990 1.1 dyoung rf = rtw_max2820_create(&sc->sc_regs, rf_write, 0); 3991 1.1 dyoung sc->sc_pwrstate_cb = rtw_maxim_pwrstate; 3992 1.1 dyoung break; 3993 1.1 dyoung case RTW_RFCHIPID_PHILIPS: 3994 1.1 dyoung rf = rtw_sa2400_create(&sc->sc_regs, rf_write, digphy); 3995 1.1 dyoung sc->sc_pwrstate_cb = rtw_philips_pwrstate; 3996 1.1 dyoung break; 3997 1.10 dyoung case RTW_RFCHIPID_RFMD: 3998 1.10 dyoung /* XXX RFMD has no RF constructor */ 3999 1.10 dyoung sc->sc_pwrstate_cb = rtw_rfmd_pwrstate; 4000 1.10 dyoung /*FALLTHROUGH*/ 4001 1.1 dyoung default: 4002 1.1 dyoung return NULL; 4003 1.1 dyoung } 4004 1.1 dyoung rf->rf_continuous_tx_cb = 4005 1.1 dyoung (rtw_continuous_tx_cb_t)rtw_continuous_tx_enable; 4006 1.1 dyoung rf->rf_continuous_tx_arg = (void *)sc; 4007 1.1 dyoung return rf; 4008 1.1 dyoung } 4009 1.1 dyoung 4010 1.1 dyoung /* Revision C and later use a different PHY delay setting than 4011 1.1 dyoung * revisions A and B. 4012 1.1 dyoung */ 4013 1.37 dyoung static uint8_t 4014 1.46 dyoung rtw_check_phydelay(struct rtw_regs *regs, uint32_t old_rcr) 4015 1.1 dyoung { 4016 1.1 dyoung #define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV) 4017 1.1 dyoung #define REVC (REVAB | RTW_RCR_RXFTH_WHOLE) 4018 1.1 dyoung 4019 1.75 dyoung uint8_t phydelay = __SHIFTIN(0x6, RTW_PHYDELAY_PHYDELAY); 4020 1.1 dyoung 4021 1.1 dyoung RTW_WRITE(regs, RTW_RCR, REVAB); 4022 1.8 dyoung RTW_WBW(regs, RTW_RCR, RTW_RCR); 4023 1.1 dyoung RTW_WRITE(regs, RTW_RCR, REVC); 4024 1.1 dyoung 4025 1.1 dyoung RTW_WBR(regs, RTW_RCR, RTW_RCR); 4026 1.1 dyoung if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC) 4027 1.1 dyoung phydelay |= RTW_PHYDELAY_REVC_MAGIC; 4028 1.1 dyoung 4029 1.46 dyoung RTW_WRITE(regs, RTW_RCR, old_rcr); /* restore RCR */ 4030 1.8 dyoung RTW_SYNC(regs, RTW_RCR, RTW_RCR); 4031 1.1 dyoung 4032 1.1 dyoung return phydelay; 4033 1.1 dyoung #undef REVC 4034 1.1 dyoung } 4035 1.1 dyoung 4036 1.1 dyoung void 4037 1.1 dyoung rtw_attach(struct rtw_softc *sc) 4038 1.1 dyoung { 4039 1.48 dyoung struct ifnet *ifp = &sc->sc_if; 4040 1.53 dyoung struct ieee80211com *ic = &sc->sc_ic; 4041 1.34 dyoung struct rtw_txsoft_blk *tsb; 4042 1.42 dyoung int pri, rc; 4043 1.1 dyoung 4044 1.109 dyoung pmf_self_suspensor_init(sc->sc_dev, &sc->sc_suspensor, &sc->sc_qual); 4045 1.109 dyoung 4046 1.58 dyoung rtw_cipher_wep = ieee80211_cipher_wep; 4047 1.58 dyoung rtw_cipher_wep.ic_decap = rtw_wep_decap; 4048 1.58 dyoung 4049 1.1 dyoung NEXT_ATTACH_STATE(sc, DETACHED); 4050 1.1 dyoung 4051 1.125 nonaka sc->sc_soft_ih = softint_establish(SOFTINT_NET, rtw_softintr, sc); 4052 1.125 nonaka if (sc->sc_soft_ih == NULL) { 4053 1.125 nonaka aprint_error_dev(sc->sc_dev, "could not establish softint\n"); 4054 1.125 nonaka goto err; 4055 1.125 nonaka } 4056 1.125 nonaka 4057 1.1 dyoung switch (RTW_READ(&sc->sc_regs, RTW_TCR) & RTW_TCR_HWVERID_MASK) { 4058 1.1 dyoung case RTW_TCR_HWVERID_F: 4059 1.42 dyoung sc->sc_hwverid = 'F'; 4060 1.1 dyoung break; 4061 1.1 dyoung case RTW_TCR_HWVERID_D: 4062 1.42 dyoung sc->sc_hwverid = 'D'; 4063 1.1 dyoung break; 4064 1.1 dyoung default: 4065 1.42 dyoung sc->sc_hwverid = '?'; 4066 1.1 dyoung break; 4067 1.1 dyoung } 4068 1.98 dyoung aprint_verbose_dev(sc->sc_dev, "hardware version %c\n", 4069 1.42 dyoung sc->sc_hwverid); 4070 1.1 dyoung 4071 1.1 dyoung rc = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct rtw_descs), 4072 1.1 dyoung RTW_DESC_ALIGNMENT, 0, &sc->sc_desc_segs, 1, &sc->sc_desc_nsegs, 4073 1.1 dyoung 0); 4074 1.1 dyoung 4075 1.1 dyoung if (rc != 0) { 4076 1.98 dyoung aprint_error_dev(sc->sc_dev, 4077 1.98 dyoung "could not allocate hw descriptors, error %d\n", rc); 4078 1.1 dyoung goto err; 4079 1.1 dyoung } 4080 1.1 dyoung 4081 1.1 dyoung NEXT_ATTACH_STATE(sc, FINISH_DESC_ALLOC); 4082 1.1 dyoung 4083 1.1 dyoung rc = bus_dmamem_map(sc->sc_dmat, &sc->sc_desc_segs, 4084 1.1 dyoung sc->sc_desc_nsegs, sizeof(struct rtw_descs), 4085 1.85 christos (void **)&sc->sc_descs, BUS_DMA_COHERENT); 4086 1.1 dyoung 4087 1.1 dyoung if (rc != 0) { 4088 1.98 dyoung aprint_error_dev(sc->sc_dev, 4089 1.98 dyoung "could not map hw descriptors, error %d\n", rc); 4090 1.1 dyoung goto err; 4091 1.1 dyoung } 4092 1.1 dyoung NEXT_ATTACH_STATE(sc, FINISH_DESC_MAP); 4093 1.1 dyoung 4094 1.1 dyoung rc = bus_dmamap_create(sc->sc_dmat, sizeof(struct rtw_descs), 1, 4095 1.1 dyoung sizeof(struct rtw_descs), 0, 0, &sc->sc_desc_dmamap); 4096 1.1 dyoung 4097 1.1 dyoung if (rc != 0) { 4098 1.98 dyoung aprint_error_dev(sc->sc_dev, 4099 1.98 dyoung "could not create DMA map for hw descriptors, error %d\n", 4100 1.98 dyoung rc); 4101 1.1 dyoung goto err; 4102 1.1 dyoung } 4103 1.1 dyoung NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_CREATE); 4104 1.1 dyoung 4105 1.34 dyoung sc->sc_rxdesc_blk.rdb_dmat = sc->sc_dmat; 4106 1.34 dyoung sc->sc_rxdesc_blk.rdb_dmamap = sc->sc_desc_dmamap; 4107 1.33 dyoung 4108 1.33 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 4109 1.34 dyoung sc->sc_txdesc_blk[pri].tdb_dmat = sc->sc_dmat; 4110 1.34 dyoung sc->sc_txdesc_blk[pri].tdb_dmamap = sc->sc_desc_dmamap; 4111 1.33 dyoung } 4112 1.33 dyoung 4113 1.1 dyoung rc = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_descs, 4114 1.1 dyoung sizeof(struct rtw_descs), NULL, 0); 4115 1.1 dyoung 4116 1.1 dyoung if (rc != 0) { 4117 1.98 dyoung aprint_error_dev(sc->sc_dev, 4118 1.98 dyoung "could not load DMA map for hw descriptors, error %d\n", 4119 1.98 dyoung rc); 4120 1.1 dyoung goto err; 4121 1.1 dyoung } 4122 1.1 dyoung NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_LOAD); 4123 1.1 dyoung 4124 1.34 dyoung if (rtw_txsoft_blk_setup_all(sc) != 0) 4125 1.1 dyoung goto err; 4126 1.1 dyoung NEXT_ATTACH_STATE(sc, FINISH_TXCTLBLK_SETUP); 4127 1.1 dyoung 4128 1.1 dyoung rtw_txdesc_blk_setup_all(sc); 4129 1.1 dyoung 4130 1.1 dyoung NEXT_ATTACH_STATE(sc, FINISH_TXDESCBLK_SETUP); 4131 1.1 dyoung 4132 1.34 dyoung sc->sc_rxdesc_blk.rdb_desc = &sc->sc_descs->hd_rx[0]; 4133 1.1 dyoung 4134 1.1 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 4135 1.34 dyoung tsb = &sc->sc_txsoft_blk[pri]; 4136 1.1 dyoung 4137 1.1 dyoung if ((rc = rtw_txdesc_dmamaps_create(sc->sc_dmat, 4138 1.34 dyoung &tsb->tsb_desc[0], tsb->tsb_ndesc)) != 0) { 4139 1.98 dyoung aprint_error_dev(sc->sc_dev, 4140 1.98 dyoung "could not load DMA map for hw tx descriptors, " 4141 1.98 dyoung "error %d\n", rc); 4142 1.1 dyoung goto err; 4143 1.1 dyoung } 4144 1.1 dyoung } 4145 1.1 dyoung 4146 1.1 dyoung NEXT_ATTACH_STATE(sc, FINISH_TXMAPS_CREATE); 4147 1.34 dyoung if ((rc = rtw_rxdesc_dmamaps_create(sc->sc_dmat, &sc->sc_rxsoft[0], 4148 1.132 msaitoh RTW_RXQLEN)) != 0) { 4149 1.98 dyoung aprint_error_dev(sc->sc_dev, 4150 1.98 dyoung "could not load DMA map for hw rx descriptors, error %d\n", 4151 1.98 dyoung rc); 4152 1.1 dyoung goto err; 4153 1.1 dyoung } 4154 1.1 dyoung NEXT_ATTACH_STATE(sc, FINISH_RXMAPS_CREATE); 4155 1.1 dyoung 4156 1.1 dyoung /* Reset the chip to a known state. */ 4157 1.1 dyoung if (rtw_reset(sc) != 0) 4158 1.1 dyoung goto err; 4159 1.1 dyoung NEXT_ATTACH_STATE(sc, FINISH_RESET); 4160 1.1 dyoung 4161 1.1 dyoung sc->sc_rcr = RTW_READ(&sc->sc_regs, RTW_RCR); 4162 1.1 dyoung 4163 1.1 dyoung if ((sc->sc_rcr & RTW_RCR_9356SEL) != 0) 4164 1.1 dyoung sc->sc_flags |= RTW_F_9356SROM; 4165 1.1 dyoung 4166 1.1 dyoung if (rtw_srom_read(&sc->sc_regs, sc->sc_flags, &sc->sc_srom, 4167 1.98 dyoung sc->sc_dev) != 0) 4168 1.1 dyoung goto err; 4169 1.1 dyoung 4170 1.1 dyoung NEXT_ATTACH_STATE(sc, FINISH_READ_SROM); 4171 1.1 dyoung 4172 1.1 dyoung if (rtw_srom_parse(&sc->sc_srom, &sc->sc_flags, &sc->sc_csthr, 4173 1.1 dyoung &sc->sc_rfchipid, &sc->sc_rcr, &sc->sc_locale, 4174 1.98 dyoung sc->sc_dev) != 0) { 4175 1.98 dyoung aprint_error_dev(sc->sc_dev, 4176 1.98 dyoung "attach failed, malformed serial ROM\n"); 4177 1.1 dyoung goto err; 4178 1.1 dyoung } 4179 1.1 dyoung 4180 1.98 dyoung aprint_verbose_dev(sc->sc_dev, "%s PHY\n", 4181 1.10 dyoung ((sc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog"); 4182 1.10 dyoung 4183 1.98 dyoung aprint_verbose_dev(sc->sc_dev, "carrier-sense threshold %u\n", 4184 1.98 dyoung sc->sc_csthr); 4185 1.1 dyoung 4186 1.1 dyoung NEXT_ATTACH_STATE(sc, FINISH_PARSE_SROM); 4187 1.1 dyoung 4188 1.42 dyoung sc->sc_rf = rtw_rf_attach(sc, sc->sc_rfchipid, 4189 1.1 dyoung sc->sc_flags & RTW_F_DIGPHY); 4190 1.1 dyoung 4191 1.1 dyoung if (sc->sc_rf == NULL) { 4192 1.98 dyoung aprint_verbose_dev(sc->sc_dev, 4193 1.98 dyoung "attach failed, could not attach RF\n"); 4194 1.1 dyoung goto err; 4195 1.1 dyoung } 4196 1.1 dyoung 4197 1.1 dyoung NEXT_ATTACH_STATE(sc, FINISH_RF_ATTACH); 4198 1.1 dyoung 4199 1.1 dyoung sc->sc_phydelay = rtw_check_phydelay(&sc->sc_regs, sc->sc_rcr); 4200 1.1 dyoung 4201 1.21 dyoung RTW_DPRINTF(RTW_DEBUG_ATTACH, 4202 1.98 dyoung ("%s: PHY delay %d\n", device_xname(sc->sc_dev), sc->sc_phydelay)); 4203 1.1 dyoung 4204 1.1 dyoung if (sc->sc_locale == RTW_LOCALE_UNKNOWN) 4205 1.58 dyoung rtw_identify_country(&sc->sc_regs, &sc->sc_locale); 4206 1.1 dyoung 4207 1.98 dyoung rtw_init_channels(sc->sc_locale, &sc->sc_ic.ic_channels, sc->sc_dev); 4208 1.1 dyoung 4209 1.1 dyoung if (rtw_identify_sta(&sc->sc_regs, &sc->sc_ic.ic_myaddr, 4210 1.98 dyoung sc->sc_dev) != 0) 4211 1.1 dyoung goto err; 4212 1.1 dyoung NEXT_ATTACH_STATE(sc, FINISH_ID_STA); 4213 1.1 dyoung 4214 1.98 dyoung rtw_setifprops(ifp, device_xname(sc->sc_dev), (void*)sc); 4215 1.1 dyoung 4216 1.56 gdt IFQ_SET_READY(&ifp->if_snd); 4217 1.1 dyoung 4218 1.48 dyoung sc->sc_ic.ic_ifp = ifp; 4219 1.1 dyoung rtw_set80211props(&sc->sc_ic); 4220 1.1 dyoung 4221 1.45 dyoung rtw_led_attach(&sc->sc_led_state, (void *)sc); 4222 1.127 msaitoh NEXT_ATTACH_STATE(sc, FINISH_LED_ATTACH); 4223 1.42 dyoung 4224 1.1 dyoung /* 4225 1.1 dyoung * Call MI attach routines. 4226 1.1 dyoung */ 4227 1.136 riastrad if_initialize(ifp); 4228 1.125 nonaka ieee80211_ifattach(ic); 4229 1.125 nonaka /* Use common softint-based if_input */ 4230 1.125 nonaka ifp->if_percpuq = if_percpuq_create(ifp); 4231 1.125 nonaka if_register(ifp); 4232 1.1 dyoung 4233 1.1 dyoung rtw_set80211methods(&sc->sc_mtbl, &sc->sc_ic); 4234 1.1 dyoung 4235 1.1 dyoung /* possibly we should fill in our own sc_send_prresp, since 4236 1.1 dyoung * the RTL8180 is probably sending probe responses in ad hoc 4237 1.1 dyoung * mode. 4238 1.1 dyoung */ 4239 1.1 dyoung 4240 1.1 dyoung /* complete initialization */ 4241 1.48 dyoung ieee80211_media_init(&sc->sc_ic, rtw_media_change, rtw_media_status); 4242 1.89 ad callout_init(&sc->sc_scan_ch, 0); 4243 1.1 dyoung 4244 1.32 dyoung rtw_init_radiotap(sc); 4245 1.32 dyoung 4246 1.116 joerg bpf_attach2(ifp, DLT_IEEE802_11_RADIO, 4247 1.1 dyoung sizeof(struct ieee80211_frame) + 64, &sc->sc_radiobpf); 4248 1.1 dyoung 4249 1.1 dyoung NEXT_ATTACH_STATE(sc, FINISHED); 4250 1.1 dyoung 4251 1.52 dyoung ieee80211_announce(ic); 4252 1.1 dyoung return; 4253 1.1 dyoung err: 4254 1.1 dyoung rtw_detach(sc); 4255 1.1 dyoung return; 4256 1.1 dyoung } 4257 1.1 dyoung 4258 1.1 dyoung int 4259 1.1 dyoung rtw_detach(struct rtw_softc *sc) 4260 1.1 dyoung { 4261 1.48 dyoung struct ifnet *ifp = &sc->sc_if; 4262 1.95 dyoung int pri, s; 4263 1.1 dyoung 4264 1.95 dyoung s = splnet(); 4265 1.36 dyoung 4266 1.1 dyoung switch (sc->sc_attach_state) { 4267 1.1 dyoung case FINISHED: 4268 1.48 dyoung rtw_stop(ifp, 1); 4269 1.3 dyoung 4270 1.98 dyoung pmf_device_deregister(sc->sc_dev); 4271 1.1 dyoung callout_stop(&sc->sc_scan_ch); 4272 1.48 dyoung ieee80211_ifdetach(&sc->sc_ic); 4273 1.48 dyoung if_detach(ifp); 4274 1.129 mrg /*FALLTHROUGH*/ 4275 1.127 msaitoh case FINISH_LED_ATTACH: 4276 1.101 dyoung rtw_led_detach(&sc->sc_led_state); 4277 1.96 dyoung /*FALLTHROUGH*/ 4278 1.1 dyoung case FINISH_ID_STA: 4279 1.1 dyoung case FINISH_RF_ATTACH: 4280 1.1 dyoung rtw_rf_destroy(sc->sc_rf); 4281 1.1 dyoung sc->sc_rf = NULL; 4282 1.1 dyoung /*FALLTHROUGH*/ 4283 1.1 dyoung case FINISH_PARSE_SROM: 4284 1.1 dyoung case FINISH_READ_SROM: 4285 1.1 dyoung rtw_srom_free(&sc->sc_srom); 4286 1.1 dyoung /*FALLTHROUGH*/ 4287 1.1 dyoung case FINISH_RESET: 4288 1.1 dyoung case FINISH_RXMAPS_CREATE: 4289 1.34 dyoung rtw_rxdesc_dmamaps_destroy(sc->sc_dmat, &sc->sc_rxsoft[0], 4290 1.1 dyoung RTW_RXQLEN); 4291 1.1 dyoung /*FALLTHROUGH*/ 4292 1.1 dyoung case FINISH_TXMAPS_CREATE: 4293 1.1 dyoung for (pri = 0; pri < RTW_NTXPRI; pri++) { 4294 1.1 dyoung rtw_txdesc_dmamaps_destroy(sc->sc_dmat, 4295 1.34 dyoung sc->sc_txsoft_blk[pri].tsb_desc, 4296 1.34 dyoung sc->sc_txsoft_blk[pri].tsb_ndesc); 4297 1.1 dyoung } 4298 1.1 dyoung /*FALLTHROUGH*/ 4299 1.1 dyoung case FINISH_TXDESCBLK_SETUP: 4300 1.1 dyoung case FINISH_TXCTLBLK_SETUP: 4301 1.34 dyoung rtw_txsoft_blk_cleanup_all(sc); 4302 1.1 dyoung /*FALLTHROUGH*/ 4303 1.1 dyoung case FINISH_DESCMAP_LOAD: 4304 1.1 dyoung bus_dmamap_unload(sc->sc_dmat, sc->sc_desc_dmamap); 4305 1.1 dyoung /*FALLTHROUGH*/ 4306 1.1 dyoung case FINISH_DESCMAP_CREATE: 4307 1.1 dyoung bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_dmamap); 4308 1.1 dyoung /*FALLTHROUGH*/ 4309 1.1 dyoung case FINISH_DESC_MAP: 4310 1.85 christos bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_descs, 4311 1.1 dyoung sizeof(struct rtw_descs)); 4312 1.1 dyoung /*FALLTHROUGH*/ 4313 1.1 dyoung case FINISH_DESC_ALLOC: 4314 1.1 dyoung bus_dmamem_free(sc->sc_dmat, &sc->sc_desc_segs, 4315 1.1 dyoung sc->sc_desc_nsegs); 4316 1.1 dyoung /*FALLTHROUGH*/ 4317 1.1 dyoung case DETACHED: 4318 1.125 nonaka if (sc->sc_soft_ih != NULL) { 4319 1.125 nonaka softint_disestablish(sc->sc_soft_ih); 4320 1.125 nonaka sc->sc_soft_ih = NULL; 4321 1.125 nonaka } 4322 1.1 dyoung NEXT_ATTACH_STATE(sc, DETACHED); 4323 1.1 dyoung break; 4324 1.1 dyoung } 4325 1.95 dyoung splx(s); 4326 1.1 dyoung return 0; 4327 1.1 dyoung } 4328