1 1.120 nat /* $NetBSD: if_urtwn.c,v 1.120 2025/08/24 09:45:29 nat Exp $ */ 2 1.37 christos /* $OpenBSD: if_urtwn.c,v 1.42 2015/02/10 23:25:46 mpi Exp $ */ 3 1.1 nonaka 4 1.1 nonaka /*- 5 1.1 nonaka * Copyright (c) 2010 Damien Bergamini <damien.bergamini (at) free.fr> 6 1.32 nonaka * Copyright (c) 2014 Kevin Lo <kevlo (at) FreeBSD.org> 7 1.49 nat * Copyright (c) 2016 Nathanial Sloss <nathanialsloss (at) yahoo.com.au> 8 1.1 nonaka * 9 1.1 nonaka * Permission to use, copy, modify, and distribute this software for any 10 1.1 nonaka * purpose with or without fee is hereby granted, provided that the above 11 1.1 nonaka * copyright notice and this permission notice appear in all copies. 12 1.1 nonaka * 13 1.1 nonaka * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 1.1 nonaka * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 1.1 nonaka * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 1.1 nonaka * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 1.1 nonaka * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 1.1 nonaka * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 1.1 nonaka * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 1.1 nonaka */ 21 1.1 nonaka 22 1.8 christos /*- 23 1.49 nat * Driver for Realtek RTL8188CE-VAU/RTL8188CUS/RTL8188EU/RTL8188RU/RTL8192CU 24 1.49 nat * RTL8192EU. 25 1.1 nonaka */ 26 1.1 nonaka 27 1.1 nonaka #include <sys/cdefs.h> 28 1.120 nat __KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.120 2025/08/24 09:45:29 nat Exp $"); 29 1.11 jmcneill 30 1.11 jmcneill #ifdef _KERNEL_OPT 31 1.11 jmcneill #include "opt_inet.h" 32 1.51 skrll #include "opt_usb.h" 33 1.11 jmcneill #endif 34 1.1 nonaka 35 1.1 nonaka #include <sys/param.h> 36 1.1 nonaka #include <sys/sockio.h> 37 1.1 nonaka #include <sys/sysctl.h> 38 1.1 nonaka #include <sys/mbuf.h> 39 1.1 nonaka #include <sys/kernel.h> 40 1.1 nonaka #include <sys/socket.h> 41 1.1 nonaka #include <sys/systm.h> 42 1.1 nonaka #include <sys/module.h> 43 1.1 nonaka #include <sys/conf.h> 44 1.1 nonaka #include <sys/device.h> 45 1.70 msaitoh #include <sys/rndsource.h> 46 1.1 nonaka 47 1.1 nonaka #include <sys/bus.h> 48 1.1 nonaka #include <machine/endian.h> 49 1.1 nonaka #include <sys/intr.h> 50 1.1 nonaka 51 1.1 nonaka #include <net/bpf.h> 52 1.1 nonaka #include <net/if.h> 53 1.1 nonaka #include <net/if_arp.h> 54 1.1 nonaka #include <net/if_dl.h> 55 1.1 nonaka #include <net/if_ether.h> 56 1.1 nonaka #include <net/if_media.h> 57 1.1 nonaka #include <net/if_types.h> 58 1.1 nonaka 59 1.1 nonaka #include <netinet/in.h> 60 1.1 nonaka #include <netinet/in_systm.h> 61 1.1 nonaka #include <netinet/in_var.h> 62 1.1 nonaka #include <netinet/ip.h> 63 1.11 jmcneill #include <netinet/if_inarp.h> 64 1.1 nonaka 65 1.1 nonaka #include <net80211/ieee80211_netbsd.h> 66 1.1 nonaka #include <net80211/ieee80211_var.h> 67 1.1 nonaka #include <net80211/ieee80211_radiotap.h> 68 1.1 nonaka 69 1.1 nonaka #include <dev/firmload.h> 70 1.1 nonaka 71 1.1 nonaka #include <dev/usb/usb.h> 72 1.1 nonaka #include <dev/usb/usbdi.h> 73 1.1 nonaka #include <dev/usb/usbdivar.h> 74 1.1 nonaka #include <dev/usb/usbdi_util.h> 75 1.1 nonaka #include <dev/usb/usbdevs.h> 76 1.74 gson #include <dev/usb/usbhist.h> 77 1.1 nonaka 78 1.60 thorpej #include <dev/ic/rtwnreg.h> 79 1.60 thorpej #include <dev/ic/rtwn_data.h> 80 1.1 nonaka #include <dev/usb/if_urtwnreg.h> 81 1.1 nonaka #include <dev/usb/if_urtwnvar.h> 82 1.1 nonaka 83 1.12 christos /* 84 1.12 christos * The sc_write_mtx locking is to prevent sequences of writes from 85 1.12 christos * being intermingled with each other. I don't know if this is really 86 1.12 christos * needed. I have added it just to be on the safe side. 87 1.12 christos */ 88 1.12 christos 89 1.1 nonaka #ifdef URTWN_DEBUG 90 1.1 nonaka #define DBG_INIT __BIT(0) 91 1.1 nonaka #define DBG_FN __BIT(1) 92 1.1 nonaka #define DBG_TX __BIT(2) 93 1.1 nonaka #define DBG_RX __BIT(3) 94 1.1 nonaka #define DBG_STM __BIT(4) 95 1.1 nonaka #define DBG_RF __BIT(5) 96 1.1 nonaka #define DBG_REG __BIT(6) 97 1.1 nonaka #define DBG_ALL 0xffffffffU 98 1.106 mrg 99 1.106 mrg #ifndef URTWN_DEBUG_DEFAULT 100 1.106 mrg #define URTWN_DEBUG_DEFAULT 0 101 1.106 mrg #endif 102 1.106 mrg 103 1.106 mrg u_int urtwn_debug = URTWN_DEBUG_DEFAULT; 104 1.106 mrg 105 1.74 gson #define DPRINTFN(n, fmt, a, b, c, d) do { \ 106 1.74 gson if (urtwn_debug & (n)) { \ 107 1.74 gson KERNHIST_LOG(usbhist, fmt, a, b, c, d); \ 108 1.74 gson } \ 109 1.74 gson } while (/*CONSTCOND*/0) 110 1.74 gson #define URTWNHIST_FUNC() USBHIST_FUNC() 111 1.74 gson #define URTWNHIST_CALLED() do { \ 112 1.74 gson if (urtwn_debug & DBG_FN) { \ 113 1.74 gson KERNHIST_CALLED(usbhist); \ 114 1.74 gson } \ 115 1.74 gson } while(/*CONSTCOND*/0) 116 1.74 gson #define URTWNHIST_CALLARGS(fmt, a, b, c, d) do { \ 117 1.74 gson if (urtwn_debug & DBG_FN) { \ 118 1.74 gson KERNHIST_CALLARGS(usbhist, fmt, a, b, c, d); \ 119 1.74 gson } \ 120 1.74 gson } while(/*CONSTCOND*/0) 121 1.1 nonaka #else 122 1.74 gson #define DPRINTFN(n, fmt, a, b, c, d) 123 1.74 gson #define URTWNHIST_FUNC() 124 1.74 gson #define URTWNHIST_CALLED() 125 1.74 gson #define URTWNHIST_CALLARGS(fmt, a, b, c, d) 126 1.1 nonaka #endif 127 1.1 nonaka 128 1.38 christos #define URTWN_DEV(v,p) { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, 0 } 129 1.32 nonaka #define URTWN_RTL8188E_DEV(v,p) \ 130 1.38 christos { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, FLAG_RTL8188E } 131 1.49 nat #define URTWN_RTL8192EU_DEV(v,p) \ 132 1.49 nat { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, FLAG_RTL8192E } 133 1.32 nonaka static const struct urtwn_dev { 134 1.32 nonaka struct usb_devno dev; 135 1.32 nonaka uint32_t flags; 136 1.32 nonaka #define FLAG_RTL8188E __BIT(0) 137 1.49 nat #define FLAG_RTL8192E __BIT(1) 138 1.32 nonaka } urtwn_devs[] = { 139 1.32 nonaka URTWN_DEV(ABOCOM, RTL8188CU_1), 140 1.32 nonaka URTWN_DEV(ABOCOM, RTL8188CU_2), 141 1.32 nonaka URTWN_DEV(ABOCOM, RTL8192CU), 142 1.32 nonaka URTWN_DEV(ASUSTEK, RTL8192CU), 143 1.37 christos URTWN_DEV(ASUSTEK, RTL8192CU_3), 144 1.33 nonaka URTWN_DEV(ASUSTEK, USBN10NANO), 145 1.32 nonaka URTWN_DEV(AZUREWAVE, RTL8188CE_1), 146 1.32 nonaka URTWN_DEV(AZUREWAVE, RTL8188CE_2), 147 1.32 nonaka URTWN_DEV(AZUREWAVE, RTL8188CU), 148 1.37 christos URTWN_DEV(BELKIN, F7D2102), 149 1.32 nonaka URTWN_DEV(BELKIN, RTL8188CU), 150 1.37 christos URTWN_DEV(BELKIN, RTL8188CUS), 151 1.32 nonaka URTWN_DEV(BELKIN, RTL8192CU), 152 1.37 christos URTWN_DEV(BELKIN, RTL8192CU_1), 153 1.37 christos URTWN_DEV(BELKIN, RTL8192CU_2), 154 1.32 nonaka URTWN_DEV(CHICONY, RTL8188CUS_1), 155 1.32 nonaka URTWN_DEV(CHICONY, RTL8188CUS_2), 156 1.32 nonaka URTWN_DEV(CHICONY, RTL8188CUS_3), 157 1.32 nonaka URTWN_DEV(CHICONY, RTL8188CUS_4), 158 1.32 nonaka URTWN_DEV(CHICONY, RTL8188CUS_5), 159 1.37 christos URTWN_DEV(CHICONY, RTL8188CUS_6), 160 1.37 christos URTWN_DEV(COMPARE, RTL8192CU), 161 1.32 nonaka URTWN_DEV(COREGA, RTL8192CU), 162 1.37 christos URTWN_DEV(DLINK, DWA131B), 163 1.32 nonaka URTWN_DEV(DLINK, RTL8188CU), 164 1.32 nonaka URTWN_DEV(DLINK, RTL8192CU_1), 165 1.32 nonaka URTWN_DEV(DLINK, RTL8192CU_2), 166 1.32 nonaka URTWN_DEV(DLINK, RTL8192CU_3), 167 1.37 christos URTWN_DEV(DLINK, RTL8192CU_4), 168 1.32 nonaka URTWN_DEV(EDIMAX, RTL8188CU), 169 1.32 nonaka URTWN_DEV(EDIMAX, RTL8192CU), 170 1.32 nonaka URTWN_DEV(FEIXUN, RTL8188CU), 171 1.32 nonaka URTWN_DEV(FEIXUN, RTL8192CU), 172 1.32 nonaka URTWN_DEV(GUILLEMOT, HWNUP150), 173 1.37 christos URTWN_DEV(GUILLEMOT, RTL8192CU), 174 1.32 nonaka URTWN_DEV(HAWKING, RTL8192CU), 175 1.37 christos URTWN_DEV(HAWKING, RTL8192CU_2), 176 1.32 nonaka URTWN_DEV(HP3, RTL8188CU), 177 1.37 christos URTWN_DEV(IODATA, WNG150UM), 178 1.37 christos URTWN_DEV(IODATA, RTL8192CU), 179 1.32 nonaka URTWN_DEV(NETGEAR, WNA1000M), 180 1.32 nonaka URTWN_DEV(NETGEAR, RTL8192CU), 181 1.32 nonaka URTWN_DEV(NETGEAR4, RTL8188CU), 182 1.32 nonaka URTWN_DEV(NOVATECH, RTL8188CU), 183 1.32 nonaka URTWN_DEV(PLANEX2, RTL8188CU_1), 184 1.32 nonaka URTWN_DEV(PLANEX2, RTL8188CU_2), 185 1.32 nonaka URTWN_DEV(PLANEX2, RTL8192CU), 186 1.32 nonaka URTWN_DEV(PLANEX2, RTL8188CU_3), 187 1.32 nonaka URTWN_DEV(PLANEX2, RTL8188CU_4), 188 1.32 nonaka URTWN_DEV(PLANEX2, RTL8188CUS), 189 1.32 nonaka URTWN_DEV(REALTEK, RTL8188CE_0), 190 1.32 nonaka URTWN_DEV(REALTEK, RTL8188CE_1), 191 1.32 nonaka URTWN_DEV(REALTEK, RTL8188CTV), 192 1.32 nonaka URTWN_DEV(REALTEK, RTL8188CU_0), 193 1.32 nonaka URTWN_DEV(REALTEK, RTL8188CU_1), 194 1.32 nonaka URTWN_DEV(REALTEK, RTL8188CU_2), 195 1.39 leot URTWN_DEV(REALTEK, RTL8188CU_3), 196 1.32 nonaka URTWN_DEV(REALTEK, RTL8188CU_COMBO), 197 1.32 nonaka URTWN_DEV(REALTEK, RTL8188CUS), 198 1.32 nonaka URTWN_DEV(REALTEK, RTL8188RU), 199 1.32 nonaka URTWN_DEV(REALTEK, RTL8188RU_2), 200 1.37 christos URTWN_DEV(REALTEK, RTL8188RU_3), 201 1.32 nonaka URTWN_DEV(REALTEK, RTL8191CU), 202 1.32 nonaka URTWN_DEV(REALTEK, RTL8192CE), 203 1.32 nonaka URTWN_DEV(REALTEK, RTL8192CU), 204 1.32 nonaka URTWN_DEV(SITECOMEU, RTL8188CU), 205 1.32 nonaka URTWN_DEV(SITECOMEU, RTL8188CU_2), 206 1.32 nonaka URTWN_DEV(SITECOMEU, RTL8192CU), 207 1.32 nonaka URTWN_DEV(SITECOMEU, RTL8192CUR2), 208 1.37 christos URTWN_DEV(TPLINK, RTL8192CU), 209 1.32 nonaka URTWN_DEV(TRENDNET, RTL8188CU), 210 1.32 nonaka URTWN_DEV(TRENDNET, RTL8192CU), 211 1.104 brook URTWN_DEV(TRENDNET, TEW648UBM), 212 1.32 nonaka URTWN_DEV(ZYXEL, RTL8192CU), 213 1.32 nonaka 214 1.32 nonaka /* URTWN_RTL8188E */ 215 1.112 hgutch URTWN_RTL8188E_DEV(ASUSTEK, USBN10NANO_B1), 216 1.46 christos URTWN_RTL8188E_DEV(DLINK, DWA125D1), 217 1.34 nonaka URTWN_RTL8188E_DEV(ELECOM, WDC150SU2M), 218 1.108 maya URTWN_RTL8188E_DEV(MERCUSYS, MW150USV2), 219 1.32 nonaka URTWN_RTL8188E_DEV(REALTEK, RTL8188ETV), 220 1.32 nonaka URTWN_RTL8188E_DEV(REALTEK, RTL8188EU), 221 1.50 mlelstv URTWN_RTL8188E_DEV(ABOCOM, RTL8188EU), 222 1.53 jnemeth URTWN_RTL8188E_DEV(TPLINK, RTL8188EU), 223 1.85 skrll URTWN_RTL8188E_DEV(DLINK, DWA121B1), 224 1.101 jnemeth URTWN_RTL8188E_DEV(EDIMAX, EW7811UNV2), 225 1.52 skrll 226 1.49 nat /* URTWN_RTL8192EU */ 227 1.67 tih URTWN_RTL8192EU_DEV(DLINK, DWA131E), 228 1.49 nat URTWN_RTL8192EU_DEV(REALTEK, RTL8192EU), 229 1.90 nia URTWN_RTL8192EU_DEV(TPLINK, WN821NV5), 230 1.90 nia URTWN_RTL8192EU_DEV(TPLINK, WN822NV4), 231 1.90 nia URTWN_RTL8192EU_DEV(TPLINK, WN823NV2), 232 1.1 nonaka }; 233 1.32 nonaka #undef URTWN_DEV 234 1.32 nonaka #undef URTWN_RTL8188E_DEV 235 1.49 nat #undef URTWN_RTL8192EU_DEV 236 1.1 nonaka 237 1.1 nonaka static int urtwn_match(device_t, cfdata_t, void *); 238 1.1 nonaka static void urtwn_attach(device_t, device_t, void *); 239 1.1 nonaka static int urtwn_detach(device_t, int); 240 1.1 nonaka static int urtwn_activate(device_t, enum devact); 241 1.1 nonaka 242 1.1 nonaka CFATTACH_DECL_NEW(urtwn, sizeof(struct urtwn_softc), urtwn_match, 243 1.1 nonaka urtwn_attach, urtwn_detach, urtwn_activate); 244 1.1 nonaka 245 1.1 nonaka static int urtwn_open_pipes(struct urtwn_softc *); 246 1.1 nonaka static void urtwn_close_pipes(struct urtwn_softc *); 247 1.1 nonaka static int urtwn_alloc_rx_list(struct urtwn_softc *); 248 1.1 nonaka static void urtwn_free_rx_list(struct urtwn_softc *); 249 1.1 nonaka static int urtwn_alloc_tx_list(struct urtwn_softc *); 250 1.1 nonaka static void urtwn_free_tx_list(struct urtwn_softc *); 251 1.1 nonaka static void urtwn_task(void *); 252 1.1 nonaka static void urtwn_do_async(struct urtwn_softc *, 253 1.1 nonaka void (*)(struct urtwn_softc *, void *), void *, int); 254 1.1 nonaka static void urtwn_wait_async(struct urtwn_softc *); 255 1.1 nonaka static int urtwn_write_region_1(struct urtwn_softc *, uint16_t, uint8_t *, 256 1.1 nonaka int); 257 1.12 christos static void urtwn_write_1(struct urtwn_softc *, uint16_t, uint8_t); 258 1.12 christos static void urtwn_write_2(struct urtwn_softc *, uint16_t, uint16_t); 259 1.12 christos static void urtwn_write_4(struct urtwn_softc *, uint16_t, uint32_t); 260 1.12 christos static int urtwn_write_region(struct urtwn_softc *, uint16_t, uint8_t *, 261 1.12 christos int); 262 1.1 nonaka static int urtwn_read_region_1(struct urtwn_softc *, uint16_t, uint8_t *, 263 1.1 nonaka int); 264 1.12 christos static uint8_t urtwn_read_1(struct urtwn_softc *, uint16_t); 265 1.12 christos static uint16_t urtwn_read_2(struct urtwn_softc *, uint16_t); 266 1.12 christos static uint32_t urtwn_read_4(struct urtwn_softc *, uint16_t); 267 1.1 nonaka static int urtwn_fw_cmd(struct urtwn_softc *, uint8_t, const void *, int); 268 1.32 nonaka static void urtwn_r92c_rf_write(struct urtwn_softc *, int, uint8_t, 269 1.32 nonaka uint32_t); 270 1.32 nonaka static void urtwn_r88e_rf_write(struct urtwn_softc *, int, uint8_t, 271 1.32 nonaka uint32_t); 272 1.49 nat static void urtwn_r92e_rf_write(struct urtwn_softc *, int, uint8_t, 273 1.49 nat uint32_t); 274 1.1 nonaka static uint32_t urtwn_rf_read(struct urtwn_softc *, int, uint8_t); 275 1.1 nonaka static int urtwn_llt_write(struct urtwn_softc *, uint32_t, uint32_t); 276 1.1 nonaka static uint8_t urtwn_efuse_read_1(struct urtwn_softc *, uint16_t); 277 1.1 nonaka static void urtwn_efuse_read(struct urtwn_softc *); 278 1.32 nonaka static void urtwn_efuse_switch_power(struct urtwn_softc *); 279 1.1 nonaka static int urtwn_read_chipid(struct urtwn_softc *); 280 1.12 christos #ifdef URTWN_DEBUG 281 1.12 christos static void urtwn_dump_rom(struct urtwn_softc *, struct r92c_rom *); 282 1.12 christos #endif 283 1.1 nonaka static void urtwn_read_rom(struct urtwn_softc *); 284 1.32 nonaka static void urtwn_r88e_read_rom(struct urtwn_softc *); 285 1.1 nonaka static int urtwn_media_change(struct ifnet *); 286 1.1 nonaka static int urtwn_ra_init(struct urtwn_softc *); 287 1.12 christos static int urtwn_get_nettype(struct urtwn_softc *); 288 1.12 christos static void urtwn_set_nettype0_msr(struct urtwn_softc *, uint8_t); 289 1.1 nonaka static void urtwn_tsf_sync_enable(struct urtwn_softc *); 290 1.1 nonaka static void urtwn_set_led(struct urtwn_softc *, int, int); 291 1.1 nonaka static void urtwn_calib_to(void *); 292 1.1 nonaka static void urtwn_calib_to_cb(struct urtwn_softc *, void *); 293 1.1 nonaka static void urtwn_next_scan(void *); 294 1.1 nonaka static int urtwn_newstate(struct ieee80211com *, enum ieee80211_state, 295 1.1 nonaka int); 296 1.1 nonaka static void urtwn_newstate_cb(struct urtwn_softc *, void *); 297 1.1 nonaka static int urtwn_wme_update(struct ieee80211com *); 298 1.1 nonaka static void urtwn_wme_update_cb(struct urtwn_softc *, void *); 299 1.1 nonaka static void urtwn_update_avgrssi(struct urtwn_softc *, int, int8_t); 300 1.1 nonaka static int8_t urtwn_get_rssi(struct urtwn_softc *, int, void *); 301 1.32 nonaka static int8_t urtwn_r88e_get_rssi(struct urtwn_softc *, int, void *); 302 1.1 nonaka static void urtwn_rx_frame(struct urtwn_softc *, uint8_t *, int); 303 1.42 skrll static void urtwn_rxeof(struct usbd_xfer *, void *, usbd_status); 304 1.42 skrll static void urtwn_txeof(struct usbd_xfer *, void *, usbd_status); 305 1.1 nonaka static int urtwn_tx(struct urtwn_softc *, struct mbuf *, 306 1.12 christos struct ieee80211_node *, struct urtwn_tx_data *); 307 1.42 skrll static struct urtwn_tx_data * 308 1.42 skrll urtwn_get_tx_data(struct urtwn_softc *, size_t); 309 1.1 nonaka static void urtwn_start(struct ifnet *); 310 1.1 nonaka static void urtwn_watchdog(struct ifnet *); 311 1.1 nonaka static int urtwn_ioctl(struct ifnet *, u_long, void *); 312 1.32 nonaka static int urtwn_r92c_power_on(struct urtwn_softc *); 313 1.49 nat static int urtwn_r92e_power_on(struct urtwn_softc *); 314 1.32 nonaka static int urtwn_r88e_power_on(struct urtwn_softc *); 315 1.1 nonaka static int urtwn_llt_init(struct urtwn_softc *); 316 1.1 nonaka static void urtwn_fw_reset(struct urtwn_softc *); 317 1.32 nonaka static void urtwn_r88e_fw_reset(struct urtwn_softc *); 318 1.1 nonaka static int urtwn_fw_loadpage(struct urtwn_softc *, int, uint8_t *, int); 319 1.1 nonaka static int urtwn_load_firmware(struct urtwn_softc *); 320 1.32 nonaka static int urtwn_r92c_dma_init(struct urtwn_softc *); 321 1.32 nonaka static int urtwn_r88e_dma_init(struct urtwn_softc *); 322 1.1 nonaka static void urtwn_mac_init(struct urtwn_softc *); 323 1.1 nonaka static void urtwn_bb_init(struct urtwn_softc *); 324 1.1 nonaka static void urtwn_rf_init(struct urtwn_softc *); 325 1.1 nonaka static void urtwn_cam_init(struct urtwn_softc *); 326 1.1 nonaka static void urtwn_pa_bias_init(struct urtwn_softc *); 327 1.1 nonaka static void urtwn_rxfilter_init(struct urtwn_softc *); 328 1.1 nonaka static void urtwn_edca_init(struct urtwn_softc *); 329 1.107 mrg static void urtwn_write_txpower(struct urtwn_softc *, int, 330 1.107 mrg uint16_t[URTWN_RIDX_COUNT]); 331 1.22 christos static void urtwn_get_txpower(struct urtwn_softc *, size_t, u_int, u_int, 332 1.107 mrg uint16_t[URTWN_RIDX_COUNT]); 333 1.32 nonaka static void urtwn_r88e_get_txpower(struct urtwn_softc *, size_t, u_int, 334 1.107 mrg u_int, uint16_t[URTWN_RIDX_COUNT]); 335 1.1 nonaka static void urtwn_set_txpower(struct urtwn_softc *, u_int, u_int); 336 1.1 nonaka static void urtwn_set_chan(struct urtwn_softc *, struct ieee80211_channel *, 337 1.1 nonaka u_int); 338 1.1 nonaka static void urtwn_iq_calib(struct urtwn_softc *, bool); 339 1.1 nonaka static void urtwn_lc_calib(struct urtwn_softc *); 340 1.1 nonaka static void urtwn_temp_calib(struct urtwn_softc *); 341 1.1 nonaka static int urtwn_init(struct ifnet *); 342 1.1 nonaka static void urtwn_stop(struct ifnet *, int); 343 1.16 jmcneill static int urtwn_reset(struct ifnet *); 344 1.1 nonaka static void urtwn_chip_stop(struct urtwn_softc *); 345 1.26 christos static void urtwn_newassoc(struct ieee80211_node *, int); 346 1.49 nat static void urtwn_delay_ms(struct urtwn_softc *, int ms); 347 1.1 nonaka 348 1.1 nonaka /* Aliases. */ 349 1.1 nonaka #define urtwn_bb_write urtwn_write_4 350 1.1 nonaka #define urtwn_bb_read urtwn_read_4 351 1.1 nonaka 352 1.32 nonaka #define urtwn_lookup(d,v,p) ((const struct urtwn_dev *)usb_lookup(d,v,p)) 353 1.32 nonaka 354 1.48 nat static const uint16_t addaReg[] = { 355 1.48 nat R92C_FPGA0_XCD_SWITCHCTL, R92C_BLUETOOTH, R92C_RX_WAIT_CCA, 356 1.48 nat R92C_TX_CCK_RFON, R92C_TX_CCK_BBON, R92C_TX_OFDM_RFON, 357 1.48 nat R92C_TX_OFDM_BBON, R92C_TX_TO_RX, R92C_TX_TO_TX, R92C_RX_CCK, 358 1.48 nat R92C_RX_OFDM, R92C_RX_WAIT_RIFS, R92C_RX_TO_RX, 359 1.48 nat R92C_STANDBY, R92C_SLEEP, R92C_PMPD_ANAEN 360 1.48 nat }; 361 1.48 nat 362 1.1 nonaka static int 363 1.1 nonaka urtwn_match(device_t parent, cfdata_t match, void *aux) 364 1.1 nonaka { 365 1.1 nonaka struct usb_attach_arg *uaa = aux; 366 1.1 nonaka 367 1.49 nat return urtwn_lookup(urtwn_devs, uaa->uaa_vendor, uaa->uaa_product) != 368 1.49 nat NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 369 1.1 nonaka } 370 1.1 nonaka 371 1.1 nonaka static void 372 1.1 nonaka urtwn_attach(device_t parent, device_t self, void *aux) 373 1.1 nonaka { 374 1.1 nonaka struct urtwn_softc *sc = device_private(self); 375 1.1 nonaka struct ieee80211com *ic = &sc->sc_ic; 376 1.1 nonaka struct ifnet *ifp = &sc->sc_if; 377 1.1 nonaka struct usb_attach_arg *uaa = aux; 378 1.1 nonaka char *devinfop; 379 1.32 nonaka const struct urtwn_dev *dev; 380 1.47 nat usb_device_request_t req; 381 1.22 christos size_t i; 382 1.22 christos int error; 383 1.1 nonaka 384 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 385 1.74 gson 386 1.1 nonaka sc->sc_dev = self; 387 1.42 skrll sc->sc_udev = uaa->uaa_device; 388 1.1 nonaka 389 1.32 nonaka sc->chip = 0; 390 1.42 skrll dev = urtwn_lookup(urtwn_devs, uaa->uaa_vendor, uaa->uaa_product); 391 1.32 nonaka if (dev != NULL && ISSET(dev->flags, FLAG_RTL8188E)) 392 1.32 nonaka SET(sc->chip, URTWN_CHIP_88E); 393 1.49 nat if (dev != NULL && ISSET(dev->flags, FLAG_RTL8192E)) 394 1.49 nat SET(sc->chip, URTWN_CHIP_92EU); 395 1.32 nonaka 396 1.1 nonaka aprint_naive("\n"); 397 1.1 nonaka aprint_normal("\n"); 398 1.1 nonaka 399 1.1 nonaka devinfop = usbd_devinfo_alloc(sc->sc_udev, 0); 400 1.1 nonaka aprint_normal_dev(self, "%s\n", devinfop); 401 1.1 nonaka usbd_devinfo_free(devinfop); 402 1.1 nonaka 403 1.47 nat req.bmRequestType = UT_WRITE_DEVICE; 404 1.47 nat req.bRequest = UR_SET_FEATURE; 405 1.47 nat USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP); 406 1.47 nat USETW(req.wIndex, UHF_PORT_SUSPEND); 407 1.47 nat USETW(req.wLength, 0); 408 1.47 nat 409 1.47 nat (void) usbd_do_request(sc->sc_udev, &req, 0); 410 1.47 nat 411 1.80 skrll cv_init(&sc->sc_task_cv, "urtwntsk"); 412 1.1 nonaka mutex_init(&sc->sc_task_mtx, MUTEX_DEFAULT, IPL_NET); 413 1.12 christos mutex_init(&sc->sc_tx_mtx, MUTEX_DEFAULT, IPL_NONE); 414 1.49 nat mutex_init(&sc->sc_rx_mtx, MUTEX_DEFAULT, IPL_NONE); 415 1.1 nonaka mutex_init(&sc->sc_fwcmd_mtx, MUTEX_DEFAULT, IPL_NONE); 416 1.12 christos mutex_init(&sc->sc_write_mtx, MUTEX_DEFAULT, IPL_NONE); 417 1.1 nonaka 418 1.18 jmcneill usb_init_task(&sc->sc_task, urtwn_task, sc, 0); 419 1.1 nonaka 420 1.1 nonaka callout_init(&sc->sc_scan_to, 0); 421 1.1 nonaka callout_setfunc(&sc->sc_scan_to, urtwn_next_scan, sc); 422 1.1 nonaka callout_init(&sc->sc_calib_to, 0); 423 1.1 nonaka callout_setfunc(&sc->sc_calib_to, urtwn_calib_to, sc); 424 1.1 nonaka 425 1.72 mrg rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 426 1.72 mrg RND_TYPE_NET, RND_FLAG_DEFAULT); 427 1.72 mrg 428 1.6 skrll error = usbd_set_config_no(sc->sc_udev, 1, 0); 429 1.6 skrll if (error != 0) { 430 1.6 skrll aprint_error_dev(self, "failed to set configuration" 431 1.6 skrll ", err=%s\n", usbd_errstr(error)); 432 1.1 nonaka goto fail; 433 1.1 nonaka } 434 1.1 nonaka 435 1.1 nonaka /* Get the first interface handle. */ 436 1.1 nonaka error = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface); 437 1.1 nonaka if (error != 0) { 438 1.1 nonaka aprint_error_dev(self, "could not get interface handle\n"); 439 1.1 nonaka goto fail; 440 1.1 nonaka } 441 1.1 nonaka 442 1.1 nonaka error = urtwn_read_chipid(sc); 443 1.1 nonaka if (error != 0) { 444 1.1 nonaka aprint_error_dev(self, "unsupported test chip\n"); 445 1.1 nonaka goto fail; 446 1.1 nonaka } 447 1.1 nonaka 448 1.1 nonaka /* Determine number of Tx/Rx chains. */ 449 1.1 nonaka if (sc->chip & URTWN_CHIP_92C) { 450 1.1 nonaka sc->ntxchains = (sc->chip & URTWN_CHIP_92C_1T2R) ? 1 : 2; 451 1.1 nonaka sc->nrxchains = 2; 452 1.49 nat } else if (sc->chip & URTWN_CHIP_92EU) { 453 1.49 nat sc->ntxchains = 2; 454 1.49 nat sc->nrxchains = 2; 455 1.1 nonaka } else { 456 1.1 nonaka sc->ntxchains = 1; 457 1.1 nonaka sc->nrxchains = 1; 458 1.1 nonaka } 459 1.32 nonaka 460 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_88E) || 461 1.49 nat ISSET(sc->chip, URTWN_CHIP_92EU)) 462 1.32 nonaka urtwn_r88e_read_rom(sc); 463 1.32 nonaka else 464 1.32 nonaka urtwn_read_rom(sc); 465 1.1 nonaka 466 1.22 christos aprint_normal_dev(self, "MAC/BB RTL%s, RF 6052 %zdT%zdR, address %s\n", 467 1.49 nat (sc->chip & URTWN_CHIP_92EU) ? "8192EU" : 468 1.1 nonaka (sc->chip & URTWN_CHIP_92C) ? "8192CU" : 469 1.32 nonaka (sc->chip & URTWN_CHIP_88E) ? "8188EU" : 470 1.1 nonaka (sc->board_type == R92C_BOARD_TYPE_HIGHPA) ? "8188RU" : 471 1.1 nonaka (sc->board_type == R92C_BOARD_TYPE_MINICARD) ? "8188CE-VAU" : 472 1.1 nonaka "8188CUS", sc->ntxchains, sc->nrxchains, 473 1.1 nonaka ether_sprintf(ic->ic_myaddr)); 474 1.1 nonaka 475 1.1 nonaka error = urtwn_open_pipes(sc); 476 1.1 nonaka if (error != 0) { 477 1.1 nonaka aprint_error_dev(sc->sc_dev, "could not open pipes\n"); 478 1.1 nonaka goto fail; 479 1.1 nonaka } 480 1.1 nonaka aprint_normal_dev(self, "%d rx pipe%s, %d tx pipe%s\n", 481 1.1 nonaka sc->rx_npipe, sc->rx_npipe > 1 ? "s" : "", 482 1.1 nonaka sc->tx_npipe, sc->tx_npipe > 1 ? "s" : ""); 483 1.1 nonaka 484 1.1 nonaka /* 485 1.1 nonaka * Setup the 802.11 device. 486 1.1 nonaka */ 487 1.1 nonaka ic->ic_ifp = ifp; 488 1.1 nonaka ic->ic_phytype = IEEE80211_T_OFDM; /* Not only, but not used. */ 489 1.1 nonaka ic->ic_opmode = IEEE80211_M_STA; /* Default to BSS mode. */ 490 1.1 nonaka ic->ic_state = IEEE80211_S_INIT; 491 1.1 nonaka 492 1.1 nonaka /* Set device capabilities. */ 493 1.1 nonaka ic->ic_caps = 494 1.1 nonaka IEEE80211_C_MONITOR | /* Monitor mode supported. */ 495 1.26 christos IEEE80211_C_IBSS | /* IBSS mode supported */ 496 1.26 christos IEEE80211_C_HOSTAP | /* HostAp mode supported */ 497 1.1 nonaka IEEE80211_C_SHPREAMBLE | /* Short preamble supported. */ 498 1.1 nonaka IEEE80211_C_SHSLOT | /* Short slot time supported. */ 499 1.1 nonaka IEEE80211_C_WME | /* 802.11e */ 500 1.1 nonaka IEEE80211_C_WPA; /* 802.11i */ 501 1.1 nonaka 502 1.1 nonaka /* Set supported .11b and .11g rates. */ 503 1.1 nonaka ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; 504 1.1 nonaka ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g; 505 1.1 nonaka 506 1.1 nonaka /* Set supported .11b and .11g channels (1 through 14). */ 507 1.1 nonaka for (i = 1; i <= 14; i++) { 508 1.1 nonaka ic->ic_channels[i].ic_freq = 509 1.1 nonaka ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); 510 1.1 nonaka ic->ic_channels[i].ic_flags = 511 1.1 nonaka IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | 512 1.1 nonaka IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; 513 1.1 nonaka } 514 1.1 nonaka 515 1.1 nonaka ifp->if_softc = sc; 516 1.1 nonaka ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 517 1.1 nonaka ifp->if_init = urtwn_init; 518 1.1 nonaka ifp->if_ioctl = urtwn_ioctl; 519 1.1 nonaka ifp->if_start = urtwn_start; 520 1.1 nonaka ifp->if_watchdog = urtwn_watchdog; 521 1.1 nonaka IFQ_SET_READY(&ifp->if_snd); 522 1.1 nonaka memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 523 1.1 nonaka 524 1.65 mlelstv if_initialize(ifp); 525 1.1 nonaka ieee80211_ifattach(ic); 526 1.16 jmcneill 527 1.1 nonaka /* override default methods */ 528 1.26 christos ic->ic_newassoc = urtwn_newassoc; 529 1.16 jmcneill ic->ic_reset = urtwn_reset; 530 1.1 nonaka ic->ic_wme.wme_update = urtwn_wme_update; 531 1.1 nonaka 532 1.1 nonaka /* Override state transition machine. */ 533 1.1 nonaka sc->sc_newstate = ic->ic_newstate; 534 1.1 nonaka ic->ic_newstate = urtwn_newstate; 535 1.84 thorpej 536 1.84 thorpej /* XXX media locking needs revisiting */ 537 1.84 thorpej mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB); 538 1.84 thorpej ieee80211_media_init_with_lock(ic, 539 1.84 thorpej urtwn_media_change, ieee80211_media_status, &sc->sc_media_mtx); 540 1.1 nonaka 541 1.1 nonaka bpf_attach2(ifp, DLT_IEEE802_11_RADIO, 542 1.1 nonaka sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, 543 1.1 nonaka &sc->sc_drvbpf); 544 1.1 nonaka 545 1.1 nonaka sc->sc_rxtap_len = sizeof(sc->sc_rxtapu); 546 1.1 nonaka sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); 547 1.1 nonaka sc->sc_rxtap.wr_ihdr.it_present = htole32(URTWN_RX_RADIOTAP_PRESENT); 548 1.1 nonaka 549 1.1 nonaka sc->sc_txtap_len = sizeof(sc->sc_txtapu); 550 1.1 nonaka sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); 551 1.1 nonaka sc->sc_txtap.wt_ihdr.it_present = htole32(URTWN_TX_RADIOTAP_PRESENT); 552 1.1 nonaka 553 1.65 mlelstv ifp->if_percpuq = if_percpuq_create(ifp); 554 1.65 mlelstv if_register(ifp); 555 1.65 mlelstv 556 1.1 nonaka ieee80211_announce(ic); 557 1.1 nonaka 558 1.1 nonaka usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); 559 1.1 nonaka 560 1.30 mrg if (!pmf_device_register(self, NULL, NULL)) 561 1.30 mrg aprint_error_dev(self, "couldn't establish power handler\n"); 562 1.30 mrg 563 1.1 nonaka SET(sc->sc_flags, URTWN_FLAG_ATTACHED); 564 1.1 nonaka return; 565 1.1 nonaka 566 1.1 nonaka fail: 567 1.1 nonaka sc->sc_dying = 1; 568 1.1 nonaka aprint_error_dev(self, "attach failed\n"); 569 1.1 nonaka } 570 1.1 nonaka 571 1.1 nonaka static int 572 1.1 nonaka urtwn_detach(device_t self, int flags) 573 1.1 nonaka { 574 1.1 nonaka struct urtwn_softc *sc = device_private(self); 575 1.1 nonaka struct ifnet *ifp = &sc->sc_if; 576 1.1 nonaka int s; 577 1.1 nonaka 578 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 579 1.1 nonaka 580 1.31 christos pmf_device_deregister(self); 581 1.31 christos 582 1.1 nonaka s = splusb(); 583 1.1 nonaka 584 1.1 nonaka sc->sc_dying = 1; 585 1.1 nonaka 586 1.61 riastrad callout_halt(&sc->sc_scan_to, NULL); 587 1.61 riastrad callout_halt(&sc->sc_calib_to, NULL); 588 1.1 nonaka 589 1.1 nonaka if (ISSET(sc->sc_flags, URTWN_FLAG_ATTACHED)) { 590 1.1 nonaka urtwn_stop(ifp, 0); 591 1.63 riastrad usb_rem_task_wait(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER, 592 1.63 riastrad NULL); 593 1.1 nonaka 594 1.1 nonaka ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 595 1.1 nonaka bpf_detach(ifp); 596 1.1 nonaka ieee80211_ifdetach(&sc->sc_ic); 597 1.1 nonaka if_detach(ifp); 598 1.1 nonaka 599 1.87 mrg mutex_destroy(&sc->sc_media_mtx); 600 1.87 mrg 601 1.42 skrll /* Close Tx/Rx pipes. Abort done by urtwn_stop. */ 602 1.1 nonaka urtwn_close_pipes(sc); 603 1.1 nonaka } 604 1.1 nonaka 605 1.1 nonaka splx(s); 606 1.1 nonaka 607 1.1 nonaka usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); 608 1.1 nonaka 609 1.72 mrg rnd_detach_source(&sc->rnd_source); 610 1.72 mrg 611 1.1 nonaka callout_destroy(&sc->sc_scan_to); 612 1.1 nonaka callout_destroy(&sc->sc_calib_to); 613 1.12 christos 614 1.80 skrll cv_destroy(&sc->sc_task_cv); 615 1.12 christos mutex_destroy(&sc->sc_write_mtx); 616 1.1 nonaka mutex_destroy(&sc->sc_fwcmd_mtx); 617 1.1 nonaka mutex_destroy(&sc->sc_tx_mtx); 618 1.49 nat mutex_destroy(&sc->sc_rx_mtx); 619 1.1 nonaka mutex_destroy(&sc->sc_task_mtx); 620 1.1 nonaka 621 1.42 skrll return 0; 622 1.1 nonaka } 623 1.1 nonaka 624 1.1 nonaka static int 625 1.1 nonaka urtwn_activate(device_t self, enum devact act) 626 1.1 nonaka { 627 1.1 nonaka struct urtwn_softc *sc = device_private(self); 628 1.1 nonaka 629 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 630 1.1 nonaka 631 1.1 nonaka switch (act) { 632 1.1 nonaka case DVACT_DEACTIVATE: 633 1.1 nonaka if_deactivate(sc->sc_ic.ic_ifp); 634 1.42 skrll return 0; 635 1.1 nonaka default: 636 1.42 skrll return EOPNOTSUPP; 637 1.1 nonaka } 638 1.1 nonaka } 639 1.1 nonaka 640 1.1 nonaka static int 641 1.1 nonaka urtwn_open_pipes(struct urtwn_softc *sc) 642 1.1 nonaka { 643 1.1 nonaka /* Bulk-out endpoints addresses (from highest to lowest prio). */ 644 1.55 skrll static uint8_t epaddr[R92C_MAX_EPOUT]; 645 1.55 skrll static uint8_t rxepaddr[R92C_MAX_EPIN]; 646 1.1 nonaka usb_interface_descriptor_t *id; 647 1.1 nonaka usb_endpoint_descriptor_t *ed; 648 1.49 nat size_t i, ntx = 0, nrx = 0; 649 1.22 christos int error; 650 1.1 nonaka 651 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 652 1.1 nonaka 653 1.1 nonaka /* Determine the number of bulk-out pipes. */ 654 1.1 nonaka id = usbd_get_interface_descriptor(sc->sc_iface); 655 1.1 nonaka for (i = 0; i < id->bNumEndpoints; i++) { 656 1.1 nonaka ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); 657 1.55 skrll if (ed == NULL || UE_GET_XFERTYPE(ed->bmAttributes) != UE_BULK) { 658 1.55 skrll continue; 659 1.55 skrll } 660 1.55 skrll if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) { 661 1.55 skrll if (ntx < sizeof(epaddr)) 662 1.55 skrll epaddr[ntx] = ed->bEndpointAddress; 663 1.1 nonaka ntx++; 664 1.49 nat } 665 1.55 skrll if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) { 666 1.55 skrll if (nrx < sizeof(rxepaddr)) 667 1.55 skrll rxepaddr[nrx] = ed->bEndpointAddress; 668 1.49 nat nrx++; 669 1.49 nat } 670 1.1 nonaka } 671 1.55 skrll if (nrx == 0 || nrx > R92C_MAX_EPIN) { 672 1.55 skrll aprint_error_dev(sc->sc_dev, 673 1.55 skrll "%zd: invalid number of Rx bulk pipes\n", nrx); 674 1.55 skrll return EIO; 675 1.55 skrll } 676 1.1 nonaka if (ntx == 0 || ntx > R92C_MAX_EPOUT) { 677 1.1 nonaka aprint_error_dev(sc->sc_dev, 678 1.22 christos "%zd: invalid number of Tx bulk pipes\n", ntx); 679 1.42 skrll return EIO; 680 1.1 nonaka } 681 1.74 gson DPRINTFN(DBG_INIT, "found %jd/%jd bulk-in/out pipes", 682 1.74 gson nrx, ntx, 0, 0); 683 1.49 nat sc->rx_npipe = nrx; 684 1.1 nonaka sc->tx_npipe = ntx; 685 1.1 nonaka 686 1.1 nonaka /* Open bulk-in pipe at address 0x81. */ 687 1.49 nat for (i = 0; i < nrx; i++) { 688 1.49 nat error = usbd_open_pipe(sc->sc_iface, rxepaddr[i], 689 1.49 nat USBD_EXCLUSIVE_USE, &sc->rx_pipe[i]); 690 1.49 nat if (error != 0) { 691 1.49 nat aprint_error_dev(sc->sc_dev, 692 1.83 christos "could not open Rx bulk pipe 0x%02x: %d\n", 693 1.49 nat rxepaddr[i], error); 694 1.49 nat goto fail; 695 1.49 nat } 696 1.1 nonaka } 697 1.1 nonaka 698 1.1 nonaka /* Open bulk-out pipes (up to 3). */ 699 1.1 nonaka for (i = 0; i < ntx; i++) { 700 1.1 nonaka error = usbd_open_pipe(sc->sc_iface, epaddr[i], 701 1.1 nonaka USBD_EXCLUSIVE_USE, &sc->tx_pipe[i]); 702 1.1 nonaka if (error != 0) { 703 1.1 nonaka aprint_error_dev(sc->sc_dev, 704 1.83 christos "could not open Tx bulk pipe 0x%02x: %d\n", 705 1.12 christos epaddr[i], error); 706 1.1 nonaka goto fail; 707 1.1 nonaka } 708 1.1 nonaka } 709 1.1 nonaka 710 1.1 nonaka /* Map 802.11 access categories to USB pipes. */ 711 1.1 nonaka sc->ac2idx[WME_AC_BK] = 712 1.1 nonaka sc->ac2idx[WME_AC_BE] = (ntx == 3) ? 2 : ((ntx == 2) ? 1 : 0); 713 1.1 nonaka sc->ac2idx[WME_AC_VI] = (ntx == 3) ? 1 : 0; 714 1.1 nonaka sc->ac2idx[WME_AC_VO] = 0; /* Always use highest prio. */ 715 1.1 nonaka 716 1.1 nonaka fail: 717 1.1 nonaka if (error != 0) 718 1.1 nonaka urtwn_close_pipes(sc); 719 1.42 skrll return error; 720 1.1 nonaka } 721 1.1 nonaka 722 1.1 nonaka static void 723 1.1 nonaka urtwn_close_pipes(struct urtwn_softc *sc) 724 1.1 nonaka { 725 1.42 skrll struct usbd_pipe *pipe; 726 1.22 christos size_t i; 727 1.1 nonaka 728 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 729 1.1 nonaka 730 1.49 nat /* Close Rx pipes. */ 731 1.22 christos CTASSERT(sizeof(pipe) == sizeof(void *)); 732 1.49 nat for (i = 0; i < sc->rx_npipe; i++) { 733 1.49 nat pipe = atomic_swap_ptr(&sc->rx_pipe[i], NULL); 734 1.49 nat if (pipe != NULL) { 735 1.49 nat usbd_close_pipe(pipe); 736 1.49 nat } 737 1.1 nonaka } 738 1.49 nat 739 1.1 nonaka /* Close Tx pipes. */ 740 1.49 nat for (i = 0; i < sc->tx_npipe; i++) { 741 1.22 christos pipe = atomic_swap_ptr(&sc->tx_pipe[i], NULL); 742 1.22 christos if (pipe != NULL) { 743 1.22 christos usbd_close_pipe(pipe); 744 1.22 christos } 745 1.1 nonaka } 746 1.1 nonaka } 747 1.1 nonaka 748 1.88 jdolecek static int __noinline 749 1.1 nonaka urtwn_alloc_rx_list(struct urtwn_softc *sc) 750 1.1 nonaka { 751 1.1 nonaka struct urtwn_rx_data *data; 752 1.22 christos size_t i; 753 1.22 christos int error = 0; 754 1.1 nonaka 755 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 756 1.1 nonaka 757 1.49 nat for (size_t j = 0; j < sc->rx_npipe; j++) { 758 1.49 nat TAILQ_INIT(&sc->rx_free_list[j]); 759 1.49 nat for (i = 0; i < URTWN_RX_LIST_COUNT; i++) { 760 1.49 nat data = &sc->rx_data[j][i]; 761 1.1 nonaka 762 1.49 nat data->sc = sc; /* Backpointer for callbacks. */ 763 1.113 nat data->pidx = j; 764 1.1 nonaka 765 1.49 nat error = usbd_create_xfer(sc->rx_pipe[j], URTWN_RXBUFSZ, 766 1.56 skrll 0, 0, &data->xfer); 767 1.49 nat if (error) { 768 1.49 nat aprint_error_dev(sc->sc_dev, 769 1.49 nat "could not allocate xfer\n"); 770 1.49 nat break; 771 1.49 nat } 772 1.49 nat 773 1.49 nat data->buf = usbd_get_buffer(data->xfer); 774 1.49 nat TAILQ_INSERT_TAIL(&sc->rx_free_list[j], data, next); 775 1.1 nonaka } 776 1.1 nonaka } 777 1.1 nonaka if (error != 0) 778 1.1 nonaka urtwn_free_rx_list(sc); 779 1.42 skrll return error; 780 1.1 nonaka } 781 1.1 nonaka 782 1.1 nonaka static void 783 1.1 nonaka urtwn_free_rx_list(struct urtwn_softc *sc) 784 1.1 nonaka { 785 1.42 skrll struct usbd_xfer *xfer; 786 1.22 christos size_t i; 787 1.1 nonaka 788 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 789 1.1 nonaka 790 1.1 nonaka /* NB: Caller must abort pipe first. */ 791 1.49 nat for (size_t j = 0; j < sc->rx_npipe; j++) { 792 1.49 nat for (i = 0; i < URTWN_RX_LIST_COUNT; i++) { 793 1.49 nat CTASSERT(sizeof(xfer) == sizeof(void *)); 794 1.49 nat xfer = atomic_swap_ptr(&sc->rx_data[j][i].xfer, NULL); 795 1.49 nat if (xfer != NULL) 796 1.49 nat usbd_destroy_xfer(xfer); 797 1.49 nat } 798 1.1 nonaka } 799 1.1 nonaka } 800 1.1 nonaka 801 1.88 jdolecek static int __noinline 802 1.1 nonaka urtwn_alloc_tx_list(struct urtwn_softc *sc) 803 1.1 nonaka { 804 1.1 nonaka struct urtwn_tx_data *data; 805 1.22 christos size_t i; 806 1.22 christos int error = 0; 807 1.1 nonaka 808 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 809 1.1 nonaka 810 1.12 christos mutex_enter(&sc->sc_tx_mtx); 811 1.42 skrll for (size_t j = 0; j < sc->tx_npipe; j++) { 812 1.42 skrll TAILQ_INIT(&sc->tx_free_list[j]); 813 1.42 skrll for (i = 0; i < URTWN_TX_LIST_COUNT; i++) { 814 1.42 skrll data = &sc->tx_data[j][i]; 815 1.42 skrll 816 1.42 skrll data->sc = sc; /* Backpointer for callbacks. */ 817 1.42 skrll data->pidx = j; 818 1.42 skrll 819 1.42 skrll error = usbd_create_xfer(sc->tx_pipe[j], 820 1.42 skrll URTWN_TXBUFSZ, USBD_FORCE_SHORT_XFER, 0, 821 1.42 skrll &data->xfer); 822 1.42 skrll if (error) { 823 1.42 skrll aprint_error_dev(sc->sc_dev, 824 1.42 skrll "could not allocate xfer\n"); 825 1.42 skrll goto fail; 826 1.42 skrll } 827 1.1 nonaka 828 1.42 skrll data->buf = usbd_get_buffer(data->xfer); 829 1.1 nonaka 830 1.42 skrll /* Append this Tx buffer to our free list. */ 831 1.42 skrll TAILQ_INSERT_TAIL(&sc->tx_free_list[j], data, next); 832 1.1 nonaka } 833 1.1 nonaka } 834 1.12 christos mutex_exit(&sc->sc_tx_mtx); 835 1.42 skrll return 0; 836 1.1 nonaka 837 1.1 nonaka fail: 838 1.1 nonaka urtwn_free_tx_list(sc); 839 1.12 christos mutex_exit(&sc->sc_tx_mtx); 840 1.42 skrll return error; 841 1.1 nonaka } 842 1.1 nonaka 843 1.1 nonaka static void 844 1.1 nonaka urtwn_free_tx_list(struct urtwn_softc *sc) 845 1.1 nonaka { 846 1.42 skrll struct usbd_xfer *xfer; 847 1.22 christos size_t i; 848 1.1 nonaka 849 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 850 1.1 nonaka 851 1.1 nonaka /* NB: Caller must abort pipe first. */ 852 1.42 skrll for (size_t j = 0; j < sc->tx_npipe; j++) { 853 1.42 skrll for (i = 0; i < URTWN_TX_LIST_COUNT; i++) { 854 1.42 skrll CTASSERT(sizeof(xfer) == sizeof(void *)); 855 1.42 skrll xfer = atomic_swap_ptr(&sc->tx_data[j][i].xfer, NULL); 856 1.42 skrll if (xfer != NULL) 857 1.42 skrll usbd_destroy_xfer(xfer); 858 1.42 skrll } 859 1.1 nonaka } 860 1.1 nonaka } 861 1.1 nonaka 862 1.68 christos static int 863 1.68 christos urtwn_tx_beacon(struct urtwn_softc *sc, struct mbuf *m, 864 1.68 christos struct ieee80211_node *ni) 865 1.68 christos { 866 1.68 christos struct urtwn_tx_data *data = 867 1.68 christos urtwn_get_tx_data(sc, sc->ac2idx[WME_AC_VO]); 868 1.91 riastrad 869 1.91 riastrad if (data == NULL) 870 1.91 riastrad return ENOBUFS; 871 1.91 riastrad 872 1.68 christos return urtwn_tx(sc, m, ni, data); 873 1.68 christos } 874 1.68 christos 875 1.1 nonaka static void 876 1.109 riastrad urtwn_cmdq_invariants(struct urtwn_softc *sc) 877 1.109 riastrad { 878 1.109 riastrad struct urtwn_host_cmd_ring *const ring = &sc->cmdq; 879 1.109 riastrad 880 1.109 riastrad KASSERT(mutex_owned(&sc->sc_task_mtx)); 881 1.109 riastrad KASSERTMSG((ring->cur >= 0 && ring->cur < URTWN_HOST_CMD_RING_COUNT), 882 1.109 riastrad "%s: cur=%d next=%d queued=%d", 883 1.109 riastrad device_xname(sc->sc_dev), ring->cur, ring->next, ring->queued); 884 1.109 riastrad KASSERTMSG((ring->next >= 0 && ring->next < URTWN_HOST_CMD_RING_COUNT), 885 1.109 riastrad "%s: cur=%d next=%d queued=%d", 886 1.109 riastrad device_xname(sc->sc_dev), ring->cur, ring->next, ring->queued); 887 1.109 riastrad KASSERTMSG((ring->queued >= 0 && 888 1.109 riastrad ring->queued <= URTWN_HOST_CMD_RING_COUNT), 889 1.109 riastrad "%s: %d commands queued", 890 1.109 riastrad device_xname(sc->sc_dev), ring->queued); 891 1.109 riastrad } 892 1.109 riastrad 893 1.109 riastrad static void 894 1.1 nonaka urtwn_task(void *arg) 895 1.1 nonaka { 896 1.1 nonaka struct urtwn_softc *sc = arg; 897 1.68 christos struct ieee80211com *ic = &sc->sc_ic; 898 1.1 nonaka struct urtwn_host_cmd_ring *ring = &sc->cmdq; 899 1.1 nonaka struct urtwn_host_cmd *cmd; 900 1.1 nonaka int s; 901 1.1 nonaka 902 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 903 1.79 skrll if (ic->ic_state == IEEE80211_S_RUN && 904 1.68 christos (ic->ic_opmode == IEEE80211_M_HOSTAP || 905 1.68 christos ic->ic_opmode == IEEE80211_M_IBSS)) { 906 1.68 christos 907 1.68 christos struct mbuf *m = ieee80211_beacon_alloc(ic, ic->ic_bss, 908 1.68 christos &sc->sc_bo); 909 1.68 christos if (m == NULL) { 910 1.68 christos aprint_error_dev(sc->sc_dev, 911 1.68 christos "could not allocate beacon"); 912 1.68 christos } 913 1.68 christos 914 1.68 christos if (urtwn_tx_beacon(sc, m, ic->ic_bss) != 0) { 915 1.92 yamt aprint_error_dev(sc->sc_dev, "could not send beacon\n"); 916 1.68 christos } 917 1.68 christos 918 1.68 christos /* beacon is no longer needed */ 919 1.68 christos m_freem(m); 920 1.68 christos } 921 1.1 nonaka 922 1.1 nonaka /* Process host commands. */ 923 1.1 nonaka s = splusb(); 924 1.1 nonaka mutex_spin_enter(&sc->sc_task_mtx); 925 1.109 riastrad urtwn_cmdq_invariants(sc); 926 1.1 nonaka while (ring->next != ring->cur) { 927 1.109 riastrad KASSERTMSG(ring->queued > 0, "%s: cur=%d next=%d queued=%d", 928 1.109 riastrad device_xname(sc->sc_dev), 929 1.109 riastrad ring->cur, ring->next, ring->queued); 930 1.1 nonaka cmd = &ring->cmd[ring->next]; 931 1.1 nonaka mutex_spin_exit(&sc->sc_task_mtx); 932 1.1 nonaka splx(s); 933 1.16 jmcneill /* Invoke callback with kernel lock held. */ 934 1.1 nonaka cmd->cb(sc, cmd->data); 935 1.1 nonaka s = splusb(); 936 1.1 nonaka mutex_spin_enter(&sc->sc_task_mtx); 937 1.109 riastrad urtwn_cmdq_invariants(sc); 938 1.109 riastrad KASSERTMSG(ring->queued > 0, "%s: cur=%d next=%d queued=%d", 939 1.109 riastrad device_xname(sc->sc_dev), 940 1.109 riastrad ring->cur, ring->next, ring->queued); 941 1.1 nonaka ring->queued--; 942 1.1 nonaka ring->next = (ring->next + 1) % URTWN_HOST_CMD_RING_COUNT; 943 1.1 nonaka } 944 1.80 skrll cv_broadcast(&sc->sc_task_cv); 945 1.1 nonaka mutex_spin_exit(&sc->sc_task_mtx); 946 1.1 nonaka splx(s); 947 1.1 nonaka } 948 1.1 nonaka 949 1.1 nonaka static void 950 1.1 nonaka urtwn_do_async(struct urtwn_softc *sc, void (*cb)(struct urtwn_softc *, void *), 951 1.1 nonaka void *arg, int len) 952 1.1 nonaka { 953 1.1 nonaka struct urtwn_host_cmd_ring *ring = &sc->cmdq; 954 1.1 nonaka struct urtwn_host_cmd *cmd; 955 1.109 riastrad bool schedtask = false; 956 1.1 nonaka int s; 957 1.1 nonaka 958 1.74 gson URTWNHIST_FUNC(); 959 1.74 gson URTWNHIST_CALLARGS("cb=%#jx, arg=%#jx, len=%jd", 960 1.74 gson (uintptr_t)cb, (uintptr_t)arg, len, 0); 961 1.1 nonaka 962 1.1 nonaka s = splusb(); 963 1.1 nonaka mutex_spin_enter(&sc->sc_task_mtx); 964 1.109 riastrad urtwn_cmdq_invariants(sc); 965 1.1 nonaka cmd = &ring->cmd[ring->cur]; 966 1.1 nonaka cmd->cb = cb; 967 1.1 nonaka KASSERT(len <= sizeof(cmd->data)); 968 1.1 nonaka memcpy(cmd->data, arg, len); 969 1.1 nonaka ring->cur = (ring->cur + 1) % URTWN_HOST_CMD_RING_COUNT; 970 1.1 nonaka 971 1.109 riastrad /* 972 1.109 riastrad * Schedule a task to process the command if need be. 973 1.109 riastrad */ 974 1.109 riastrad if (!sc->sc_dying) { 975 1.109 riastrad if (ring->queued == URTWN_HOST_CMD_RING_COUNT) 976 1.109 riastrad device_printf(sc->sc_dev, "command queue overflow\n"); 977 1.109 riastrad else if (ring->queued++ == 0) 978 1.109 riastrad schedtask = true; 979 1.109 riastrad } 980 1.109 riastrad mutex_spin_exit(&sc->sc_task_mtx); 981 1.109 riastrad splx(s); 982 1.109 riastrad 983 1.109 riastrad if (schedtask) 984 1.1 nonaka usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); 985 1.1 nonaka } 986 1.1 nonaka 987 1.1 nonaka static void 988 1.1 nonaka urtwn_wait_async(struct urtwn_softc *sc) 989 1.1 nonaka { 990 1.1 nonaka 991 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 992 1.1 nonaka 993 1.1 nonaka /* Wait for all queued asynchronous commands to complete. */ 994 1.80 skrll mutex_spin_enter(&sc->sc_task_mtx); 995 1.1 nonaka while (sc->cmdq.queued > 0) 996 1.80 skrll cv_wait(&sc->sc_task_cv, &sc->sc_task_mtx); 997 1.80 skrll mutex_spin_exit(&sc->sc_task_mtx); 998 1.1 nonaka } 999 1.1 nonaka 1000 1.1 nonaka static int 1001 1.1 nonaka urtwn_write_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf, 1002 1.1 nonaka int len) 1003 1.1 nonaka { 1004 1.1 nonaka usb_device_request_t req; 1005 1.1 nonaka usbd_status error; 1006 1.1 nonaka 1007 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1008 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 1009 1.12 christos 1010 1.1 nonaka req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 1011 1.1 nonaka req.bRequest = R92C_REQ_REGS; 1012 1.1 nonaka USETW(req.wValue, addr); 1013 1.1 nonaka USETW(req.wIndex, 0); 1014 1.1 nonaka USETW(req.wLength, len); 1015 1.1 nonaka error = usbd_do_request(sc->sc_udev, &req, buf); 1016 1.1 nonaka if (error != USBD_NORMAL_COMPLETION) { 1017 1.75 gson DPRINTFN(DBG_REG, "error=%jd: addr=%#jx, len=%jd", 1018 1.74 gson error, addr, len, 0); 1019 1.1 nonaka } 1020 1.42 skrll return error; 1021 1.1 nonaka } 1022 1.1 nonaka 1023 1.1 nonaka static void 1024 1.1 nonaka urtwn_write_1(struct urtwn_softc *sc, uint16_t addr, uint8_t val) 1025 1.1 nonaka { 1026 1.1 nonaka 1027 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1028 1.75 gson DPRINTFN(DBG_REG, "addr=%#jx, val=%#jx", addr, val, 0, 0); 1029 1.1 nonaka 1030 1.1 nonaka urtwn_write_region_1(sc, addr, &val, 1); 1031 1.1 nonaka } 1032 1.1 nonaka 1033 1.1 nonaka static void 1034 1.1 nonaka urtwn_write_2(struct urtwn_softc *sc, uint16_t addr, uint16_t val) 1035 1.1 nonaka { 1036 1.1 nonaka uint8_t buf[2]; 1037 1.1 nonaka 1038 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1039 1.75 gson DPRINTFN(DBG_REG, "addr=%#jx, val=%#jx", addr, val, 0, 0); 1040 1.1 nonaka 1041 1.1 nonaka buf[0] = (uint8_t)val; 1042 1.1 nonaka buf[1] = (uint8_t)(val >> 8); 1043 1.1 nonaka urtwn_write_region_1(sc, addr, buf, 2); 1044 1.1 nonaka } 1045 1.1 nonaka 1046 1.1 nonaka static void 1047 1.1 nonaka urtwn_write_4(struct urtwn_softc *sc, uint16_t addr, uint32_t val) 1048 1.1 nonaka { 1049 1.1 nonaka uint8_t buf[4]; 1050 1.1 nonaka 1051 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1052 1.75 gson DPRINTFN(DBG_REG, "addr=%#jx, val=%#jx", addr, val, 0, 0); 1053 1.1 nonaka 1054 1.1 nonaka buf[0] = (uint8_t)val; 1055 1.1 nonaka buf[1] = (uint8_t)(val >> 8); 1056 1.1 nonaka buf[2] = (uint8_t)(val >> 16); 1057 1.1 nonaka buf[3] = (uint8_t)(val >> 24); 1058 1.1 nonaka urtwn_write_region_1(sc, addr, buf, 4); 1059 1.1 nonaka } 1060 1.1 nonaka 1061 1.1 nonaka static int 1062 1.1 nonaka urtwn_write_region(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf, int len) 1063 1.1 nonaka { 1064 1.1 nonaka 1065 1.74 gson URTWNHIST_FUNC(); 1066 1.75 gson URTWNHIST_CALLARGS("addr=%#jx, len=%#jx", addr, len, 0, 0); 1067 1.1 nonaka 1068 1.1 nonaka return urtwn_write_region_1(sc, addr, buf, len); 1069 1.1 nonaka } 1070 1.1 nonaka 1071 1.1 nonaka static int 1072 1.1 nonaka urtwn_read_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf, 1073 1.1 nonaka int len) 1074 1.1 nonaka { 1075 1.1 nonaka usb_device_request_t req; 1076 1.1 nonaka usbd_status error; 1077 1.1 nonaka 1078 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1079 1.74 gson 1080 1.1 nonaka req.bmRequestType = UT_READ_VENDOR_DEVICE; 1081 1.1 nonaka req.bRequest = R92C_REQ_REGS; 1082 1.1 nonaka USETW(req.wValue, addr); 1083 1.1 nonaka USETW(req.wIndex, 0); 1084 1.1 nonaka USETW(req.wLength, len); 1085 1.1 nonaka error = usbd_do_request(sc->sc_udev, &req, buf); 1086 1.1 nonaka if (error != USBD_NORMAL_COMPLETION) { 1087 1.75 gson DPRINTFN(DBG_REG, "error=%jd: addr=%#jx, len=%jd", 1088 1.74 gson error, addr, len, 0); 1089 1.1 nonaka } 1090 1.42 skrll return error; 1091 1.1 nonaka } 1092 1.1 nonaka 1093 1.1 nonaka static uint8_t 1094 1.1 nonaka urtwn_read_1(struct urtwn_softc *sc, uint16_t addr) 1095 1.1 nonaka { 1096 1.1 nonaka uint8_t val; 1097 1.1 nonaka 1098 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1099 1.74 gson 1100 1.1 nonaka if (urtwn_read_region_1(sc, addr, &val, 1) != USBD_NORMAL_COMPLETION) 1101 1.42 skrll return 0xff; 1102 1.1 nonaka 1103 1.75 gson DPRINTFN(DBG_REG, "addr=%#jx, val=%#jx", addr, val, 0, 0); 1104 1.42 skrll return val; 1105 1.1 nonaka } 1106 1.1 nonaka 1107 1.1 nonaka static uint16_t 1108 1.1 nonaka urtwn_read_2(struct urtwn_softc *sc, uint16_t addr) 1109 1.1 nonaka { 1110 1.1 nonaka uint8_t buf[2]; 1111 1.1 nonaka uint16_t val; 1112 1.1 nonaka 1113 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1114 1.74 gson 1115 1.1 nonaka if (urtwn_read_region_1(sc, addr, buf, 2) != USBD_NORMAL_COMPLETION) 1116 1.42 skrll return 0xffff; 1117 1.1 nonaka 1118 1.1 nonaka val = LE_READ_2(&buf[0]); 1119 1.75 gson DPRINTFN(DBG_REG, "addr=%#jx, val=%#jx", addr, val, 0, 0); 1120 1.42 skrll return val; 1121 1.1 nonaka } 1122 1.1 nonaka 1123 1.1 nonaka static uint32_t 1124 1.1 nonaka urtwn_read_4(struct urtwn_softc *sc, uint16_t addr) 1125 1.1 nonaka { 1126 1.1 nonaka uint8_t buf[4]; 1127 1.1 nonaka uint32_t val; 1128 1.1 nonaka 1129 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1130 1.74 gson 1131 1.1 nonaka if (urtwn_read_region_1(sc, addr, buf, 4) != USBD_NORMAL_COMPLETION) 1132 1.42 skrll return 0xffffffff; 1133 1.1 nonaka 1134 1.1 nonaka val = LE_READ_4(&buf[0]); 1135 1.75 gson DPRINTFN(DBG_REG, "addr=%#jx, val=%#jx", addr, val, 0, 0); 1136 1.42 skrll return val; 1137 1.1 nonaka } 1138 1.1 nonaka 1139 1.1 nonaka static int 1140 1.1 nonaka urtwn_fw_cmd(struct urtwn_softc *sc, uint8_t id, const void *buf, int len) 1141 1.1 nonaka { 1142 1.1 nonaka struct r92c_fw_cmd cmd; 1143 1.1 nonaka uint8_t *cp; 1144 1.1 nonaka int fwcur; 1145 1.1 nonaka int ntries; 1146 1.1 nonaka 1147 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1148 1.74 gson DPRINTFN(DBG_REG, "id=%jd, buf=%#jx, len=%jd", id, (uintptr_t)buf, len, 0); 1149 1.1 nonaka 1150 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 1151 1.12 christos 1152 1.1 nonaka mutex_enter(&sc->sc_fwcmd_mtx); 1153 1.1 nonaka fwcur = sc->fwcur; 1154 1.1 nonaka sc->fwcur = (sc->fwcur + 1) % R92C_H2C_NBOX; 1155 1.1 nonaka 1156 1.1 nonaka /* Wait for current FW box to be empty. */ 1157 1.1 nonaka for (ntries = 0; ntries < 100; ntries++) { 1158 1.1 nonaka if (!(urtwn_read_1(sc, R92C_HMETFR) & (1 << fwcur))) 1159 1.1 nonaka break; 1160 1.97 nat urtwn_delay_ms(sc, 2); 1161 1.1 nonaka } 1162 1.1 nonaka if (ntries == 100) { 1163 1.1 nonaka aprint_error_dev(sc->sc_dev, 1164 1.1 nonaka "could not send firmware command %d\n", id); 1165 1.98 nat mutex_exit(&sc->sc_fwcmd_mtx); 1166 1.42 skrll return ETIMEDOUT; 1167 1.1 nonaka } 1168 1.1 nonaka 1169 1.1 nonaka memset(&cmd, 0, sizeof(cmd)); 1170 1.1 nonaka KASSERT(len <= sizeof(cmd.msg)); 1171 1.1 nonaka memcpy(cmd.msg, buf, len); 1172 1.1 nonaka 1173 1.1 nonaka /* Write the first word last since that will trigger the FW. */ 1174 1.1 nonaka cp = (uint8_t *)&cmd; 1175 1.49 nat cmd.id = id; 1176 1.1 nonaka if (len >= 4) { 1177 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_92EU)) { 1178 1.49 nat cmd.id |= R92C_CMD_FLAG_EXT; 1179 1.49 nat urtwn_write_region(sc, R92C_HMEBOX_EXT(fwcur), 1180 1.49 nat &cp[1], 2); 1181 1.49 nat urtwn_write_4(sc, R92C_HMEBOX(fwcur), 1182 1.49 nat cp[0] + (cp[3] << 8) + (cp[4] << 16) + 1183 1.71 msaitoh ((uint32_t)cp[5] << 24)); 1184 1.49 nat } else { 1185 1.49 nat urtwn_write_region(sc, R92E_HMEBOX_EXT(fwcur), 1186 1.49 nat &cp[4], 2); 1187 1.49 nat urtwn_write_4(sc, R92C_HMEBOX(fwcur), 1188 1.49 nat cp[0] + (cp[1] << 8) + (cp[2] << 16) + 1189 1.71 msaitoh ((uint32_t)cp[3] << 24)); 1190 1.49 nat } 1191 1.1 nonaka } else { 1192 1.1 nonaka urtwn_write_region(sc, R92C_HMEBOX(fwcur), cp, len); 1193 1.1 nonaka } 1194 1.98 nat mutex_exit(&sc->sc_fwcmd_mtx); 1195 1.1 nonaka 1196 1.42 skrll return 0; 1197 1.1 nonaka } 1198 1.1 nonaka 1199 1.32 nonaka static __inline void 1200 1.32 nonaka urtwn_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr, uint32_t val) 1201 1.32 nonaka { 1202 1.32 nonaka 1203 1.32 nonaka sc->sc_rf_write(sc, chain, addr, val); 1204 1.32 nonaka } 1205 1.32 nonaka 1206 1.1 nonaka static void 1207 1.32 nonaka urtwn_r92c_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr, 1208 1.32 nonaka uint32_t val) 1209 1.1 nonaka { 1210 1.1 nonaka 1211 1.1 nonaka urtwn_bb_write(sc, R92C_LSSI_PARAM(chain), 1212 1.1 nonaka SM(R92C_LSSI_PARAM_ADDR, addr) | SM(R92C_LSSI_PARAM_DATA, val)); 1213 1.1 nonaka } 1214 1.1 nonaka 1215 1.32 nonaka static void 1216 1.32 nonaka urtwn_r88e_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr, 1217 1.32 nonaka uint32_t val) 1218 1.32 nonaka { 1219 1.32 nonaka 1220 1.32 nonaka urtwn_bb_write(sc, R92C_LSSI_PARAM(chain), 1221 1.32 nonaka SM(R88E_LSSI_PARAM_ADDR, addr) | SM(R92C_LSSI_PARAM_DATA, val)); 1222 1.32 nonaka } 1223 1.32 nonaka 1224 1.49 nat static void 1225 1.49 nat urtwn_r92e_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr, 1226 1.49 nat uint32_t val) 1227 1.49 nat { 1228 1.49 nat 1229 1.49 nat urtwn_bb_write(sc, R92C_LSSI_PARAM(chain), 1230 1.49 nat SM(R88E_LSSI_PARAM_ADDR, addr) | SM(R92C_LSSI_PARAM_DATA, val)); 1231 1.49 nat } 1232 1.49 nat 1233 1.1 nonaka static uint32_t 1234 1.1 nonaka urtwn_rf_read(struct urtwn_softc *sc, int chain, uint8_t addr) 1235 1.1 nonaka { 1236 1.1 nonaka uint32_t reg[R92C_MAX_CHAINS], val; 1237 1.1 nonaka 1238 1.1 nonaka reg[0] = urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)); 1239 1.1 nonaka if (chain != 0) { 1240 1.1 nonaka reg[chain] = urtwn_bb_read(sc, R92C_HSSI_PARAM2(chain)); 1241 1.1 nonaka } 1242 1.1 nonaka 1243 1.1 nonaka urtwn_bb_write(sc, R92C_HSSI_PARAM2(0), 1244 1.1 nonaka reg[0] & ~R92C_HSSI_PARAM2_READ_EDGE); 1245 1.97 nat urtwn_delay_ms(sc, 1); 1246 1.1 nonaka 1247 1.1 nonaka urtwn_bb_write(sc, R92C_HSSI_PARAM2(chain), 1248 1.1 nonaka RW(reg[chain], R92C_HSSI_PARAM2_READ_ADDR, addr) | 1249 1.1 nonaka R92C_HSSI_PARAM2_READ_EDGE); 1250 1.97 nat urtwn_delay_ms(sc, 1); 1251 1.1 nonaka 1252 1.1 nonaka urtwn_bb_write(sc, R92C_HSSI_PARAM2(0), 1253 1.1 nonaka reg[0] | R92C_HSSI_PARAM2_READ_EDGE); 1254 1.97 nat urtwn_delay_ms(sc, 1); 1255 1.1 nonaka 1256 1.1 nonaka if (urtwn_bb_read(sc, R92C_HSSI_PARAM1(chain)) & R92C_HSSI_PARAM1_PI) { 1257 1.1 nonaka val = urtwn_bb_read(sc, R92C_HSPI_READBACK(chain)); 1258 1.1 nonaka } else { 1259 1.1 nonaka val = urtwn_bb_read(sc, R92C_LSSI_READBACK(chain)); 1260 1.1 nonaka } 1261 1.42 skrll return MS(val, R92C_LSSI_READBACK_DATA); 1262 1.1 nonaka } 1263 1.1 nonaka 1264 1.1 nonaka static int 1265 1.1 nonaka urtwn_llt_write(struct urtwn_softc *sc, uint32_t addr, uint32_t data) 1266 1.1 nonaka { 1267 1.1 nonaka int ntries; 1268 1.1 nonaka 1269 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 1270 1.12 christos 1271 1.1 nonaka urtwn_write_4(sc, R92C_LLT_INIT, 1272 1.1 nonaka SM(R92C_LLT_INIT_OP, R92C_LLT_INIT_OP_WRITE) | 1273 1.1 nonaka SM(R92C_LLT_INIT_ADDR, addr) | 1274 1.1 nonaka SM(R92C_LLT_INIT_DATA, data)); 1275 1.1 nonaka /* Wait for write operation to complete. */ 1276 1.1 nonaka for (ntries = 0; ntries < 20; ntries++) { 1277 1.1 nonaka if (MS(urtwn_read_4(sc, R92C_LLT_INIT), R92C_LLT_INIT_OP) == 1278 1.1 nonaka R92C_LLT_INIT_OP_NO_ACTIVE) { 1279 1.1 nonaka /* Done */ 1280 1.42 skrll return 0; 1281 1.1 nonaka } 1282 1.1 nonaka DELAY(5); 1283 1.1 nonaka } 1284 1.42 skrll return ETIMEDOUT; 1285 1.1 nonaka } 1286 1.1 nonaka 1287 1.1 nonaka static uint8_t 1288 1.1 nonaka urtwn_efuse_read_1(struct urtwn_softc *sc, uint16_t addr) 1289 1.1 nonaka { 1290 1.1 nonaka uint32_t reg; 1291 1.1 nonaka int ntries; 1292 1.1 nonaka 1293 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 1294 1.12 christos 1295 1.1 nonaka reg = urtwn_read_4(sc, R92C_EFUSE_CTRL); 1296 1.1 nonaka reg = RW(reg, R92C_EFUSE_CTRL_ADDR, addr); 1297 1.1 nonaka reg &= ~R92C_EFUSE_CTRL_VALID; 1298 1.1 nonaka urtwn_write_4(sc, R92C_EFUSE_CTRL, reg); 1299 1.1 nonaka 1300 1.1 nonaka /* Wait for read operation to complete. */ 1301 1.1 nonaka for (ntries = 0; ntries < 100; ntries++) { 1302 1.1 nonaka reg = urtwn_read_4(sc, R92C_EFUSE_CTRL); 1303 1.1 nonaka if (reg & R92C_EFUSE_CTRL_VALID) { 1304 1.1 nonaka /* Done */ 1305 1.42 skrll return MS(reg, R92C_EFUSE_CTRL_DATA); 1306 1.1 nonaka } 1307 1.1 nonaka DELAY(5); 1308 1.1 nonaka } 1309 1.1 nonaka aprint_error_dev(sc->sc_dev, 1310 1.83 christos "could not read efuse byte at address 0x%04x\n", addr); 1311 1.42 skrll return 0xff; 1312 1.1 nonaka } 1313 1.1 nonaka 1314 1.1 nonaka static void 1315 1.1 nonaka urtwn_efuse_read(struct urtwn_softc *sc) 1316 1.1 nonaka { 1317 1.1 nonaka uint8_t *rom = (uint8_t *)&sc->rom; 1318 1.1 nonaka uint32_t reg; 1319 1.1 nonaka uint16_t addr = 0; 1320 1.1 nonaka uint8_t off, msk; 1321 1.22 christos size_t i; 1322 1.1 nonaka 1323 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1324 1.1 nonaka 1325 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 1326 1.12 christos 1327 1.32 nonaka urtwn_efuse_switch_power(sc); 1328 1.32 nonaka 1329 1.1 nonaka memset(&sc->rom, 0xff, sizeof(sc->rom)); 1330 1.1 nonaka while (addr < 512) { 1331 1.1 nonaka reg = urtwn_efuse_read_1(sc, addr); 1332 1.1 nonaka if (reg == 0xff) 1333 1.1 nonaka break; 1334 1.1 nonaka addr++; 1335 1.1 nonaka off = reg >> 4; 1336 1.1 nonaka msk = reg & 0xf; 1337 1.1 nonaka for (i = 0; i < 4; i++) { 1338 1.1 nonaka if (msk & (1U << i)) 1339 1.1 nonaka continue; 1340 1.1 nonaka 1341 1.1 nonaka rom[off * 8 + i * 2 + 0] = urtwn_efuse_read_1(sc, addr); 1342 1.1 nonaka addr++; 1343 1.1 nonaka rom[off * 8 + i * 2 + 1] = urtwn_efuse_read_1(sc, addr); 1344 1.1 nonaka addr++; 1345 1.1 nonaka } 1346 1.1 nonaka } 1347 1.1 nonaka #ifdef URTWN_DEBUG 1348 1.74 gson /* Dump ROM content. */ 1349 1.74 gson for (i = 0; i < (int)sizeof(sc->rom); i++) 1350 1.74 gson DPRINTFN(DBG_INIT, "%04jx: %02jx", i, rom[i], 0, 0); 1351 1.1 nonaka #endif 1352 1.1 nonaka } 1353 1.1 nonaka 1354 1.32 nonaka static void 1355 1.32 nonaka urtwn_efuse_switch_power(struct urtwn_softc *sc) 1356 1.32 nonaka { 1357 1.32 nonaka uint32_t reg; 1358 1.32 nonaka 1359 1.32 nonaka reg = urtwn_read_2(sc, R92C_SYS_ISO_CTRL); 1360 1.32 nonaka if (!(reg & R92C_SYS_ISO_CTRL_PWC_EV12V)) { 1361 1.32 nonaka urtwn_write_2(sc, R92C_SYS_ISO_CTRL, 1362 1.32 nonaka reg | R92C_SYS_ISO_CTRL_PWC_EV12V); 1363 1.32 nonaka } 1364 1.32 nonaka reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN); 1365 1.32 nonaka if (!(reg & R92C_SYS_FUNC_EN_ELDR)) { 1366 1.32 nonaka urtwn_write_2(sc, R92C_SYS_FUNC_EN, 1367 1.32 nonaka reg | R92C_SYS_FUNC_EN_ELDR); 1368 1.32 nonaka } 1369 1.32 nonaka reg = urtwn_read_2(sc, R92C_SYS_CLKR); 1370 1.32 nonaka if ((reg & (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) != 1371 1.32 nonaka (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) { 1372 1.32 nonaka urtwn_write_2(sc, R92C_SYS_CLKR, 1373 1.32 nonaka reg | R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M); 1374 1.32 nonaka } 1375 1.32 nonaka } 1376 1.32 nonaka 1377 1.1 nonaka static int 1378 1.1 nonaka urtwn_read_chipid(struct urtwn_softc *sc) 1379 1.1 nonaka { 1380 1.1 nonaka uint32_t reg; 1381 1.1 nonaka 1382 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1383 1.1 nonaka 1384 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_88E) || 1385 1.49 nat ISSET(sc->chip, URTWN_CHIP_92EU)) 1386 1.42 skrll return 0; 1387 1.32 nonaka 1388 1.1 nonaka reg = urtwn_read_4(sc, R92C_SYS_CFG); 1389 1.1 nonaka if (reg & R92C_SYS_CFG_TRP_VAUX_EN) { 1390 1.1 nonaka /* test chip, not supported */ 1391 1.42 skrll return EIO; 1392 1.1 nonaka } 1393 1.1 nonaka if (reg & R92C_SYS_CFG_TYPE_92C) { 1394 1.1 nonaka sc->chip |= URTWN_CHIP_92C; 1395 1.1 nonaka /* Check if it is a castrated 8192C. */ 1396 1.1 nonaka if (MS(urtwn_read_4(sc, R92C_HPON_FSM), 1397 1.1 nonaka R92C_HPON_FSM_CHIP_BONDING_ID) == 1398 1.1 nonaka R92C_HPON_FSM_CHIP_BONDING_ID_92C_1T2R) { 1399 1.1 nonaka sc->chip |= URTWN_CHIP_92C_1T2R; 1400 1.1 nonaka } 1401 1.1 nonaka } 1402 1.1 nonaka if (reg & R92C_SYS_CFG_VENDOR_UMC) { 1403 1.1 nonaka sc->chip |= URTWN_CHIP_UMC; 1404 1.1 nonaka if (MS(reg, R92C_SYS_CFG_CHIP_VER_RTL) == 0) { 1405 1.1 nonaka sc->chip |= URTWN_CHIP_UMC_A_CUT; 1406 1.1 nonaka } 1407 1.1 nonaka } 1408 1.42 skrll return 0; 1409 1.1 nonaka } 1410 1.1 nonaka 1411 1.1 nonaka #ifdef URTWN_DEBUG 1412 1.1 nonaka static void 1413 1.1 nonaka urtwn_dump_rom(struct urtwn_softc *sc, struct r92c_rom *rp) 1414 1.1 nonaka { 1415 1.1 nonaka 1416 1.1 nonaka aprint_normal_dev(sc->sc_dev, 1417 1.83 christos "id 0x%04x, dbg_sel %#x, vid %#x, pid %#x\n", 1418 1.1 nonaka rp->id, rp->dbg_sel, rp->vid, rp->pid); 1419 1.1 nonaka 1420 1.1 nonaka aprint_normal_dev(sc->sc_dev, 1421 1.82 christos "usb_opt %#x, ep_setting %#x, usb_phy %#x\n", 1422 1.1 nonaka rp->usb_opt, rp->ep_setting, rp->usb_phy); 1423 1.1 nonaka 1424 1.1 nonaka aprint_normal_dev(sc->sc_dev, 1425 1.73 bad "macaddr %s\n", 1426 1.73 bad ether_sprintf(rp->macaddr)); 1427 1.1 nonaka 1428 1.1 nonaka aprint_normal_dev(sc->sc_dev, 1429 1.82 christos "string %s, subcustomer_id %#x\n", 1430 1.1 nonaka rp->string, rp->subcustomer_id); 1431 1.1 nonaka 1432 1.1 nonaka aprint_normal_dev(sc->sc_dev, 1433 1.1 nonaka "cck_tx_pwr c0: %d %d %d, c1: %d %d %d\n", 1434 1.1 nonaka rp->cck_tx_pwr[0][0], rp->cck_tx_pwr[0][1], rp->cck_tx_pwr[0][2], 1435 1.1 nonaka rp->cck_tx_pwr[1][0], rp->cck_tx_pwr[1][1], rp->cck_tx_pwr[1][2]); 1436 1.1 nonaka 1437 1.1 nonaka aprint_normal_dev(sc->sc_dev, 1438 1.1 nonaka "ht40_1s_tx_pwr c0 %d %d %d, c1 %d %d %d\n", 1439 1.1 nonaka rp->ht40_1s_tx_pwr[0][0], rp->ht40_1s_tx_pwr[0][1], 1440 1.1 nonaka rp->ht40_1s_tx_pwr[0][2], 1441 1.1 nonaka rp->ht40_1s_tx_pwr[1][0], rp->ht40_1s_tx_pwr[1][1], 1442 1.1 nonaka rp->ht40_1s_tx_pwr[1][2]); 1443 1.1 nonaka 1444 1.1 nonaka aprint_normal_dev(sc->sc_dev, 1445 1.1 nonaka "ht40_2s_tx_pwr_diff c0: %d %d %d, c1: %d %d %d\n", 1446 1.1 nonaka rp->ht40_2s_tx_pwr_diff[0] & 0xf, rp->ht40_2s_tx_pwr_diff[1] & 0xf, 1447 1.1 nonaka rp->ht40_2s_tx_pwr_diff[2] & 0xf, 1448 1.1 nonaka rp->ht40_2s_tx_pwr_diff[0] >> 4, rp->ht40_2s_tx_pwr_diff[1] & 0xf, 1449 1.1 nonaka rp->ht40_2s_tx_pwr_diff[2] >> 4); 1450 1.1 nonaka 1451 1.1 nonaka aprint_normal_dev(sc->sc_dev, 1452 1.1 nonaka "ht20_tx_pwr_diff c0: %d %d %d, c1: %d %d %d\n", 1453 1.1 nonaka rp->ht20_tx_pwr_diff[0] & 0xf, rp->ht20_tx_pwr_diff[1] & 0xf, 1454 1.1 nonaka rp->ht20_tx_pwr_diff[2] & 0xf, 1455 1.1 nonaka rp->ht20_tx_pwr_diff[0] >> 4, rp->ht20_tx_pwr_diff[1] >> 4, 1456 1.1 nonaka rp->ht20_tx_pwr_diff[2] >> 4); 1457 1.1 nonaka 1458 1.1 nonaka aprint_normal_dev(sc->sc_dev, 1459 1.1 nonaka "ofdm_tx_pwr_diff c0: %d %d %d, c1: %d %d %d\n", 1460 1.1 nonaka rp->ofdm_tx_pwr_diff[0] & 0xf, rp->ofdm_tx_pwr_diff[1] & 0xf, 1461 1.1 nonaka rp->ofdm_tx_pwr_diff[2] & 0xf, 1462 1.1 nonaka rp->ofdm_tx_pwr_diff[0] >> 4, rp->ofdm_tx_pwr_diff[1] >> 4, 1463 1.1 nonaka rp->ofdm_tx_pwr_diff[2] >> 4); 1464 1.1 nonaka 1465 1.1 nonaka aprint_normal_dev(sc->sc_dev, 1466 1.1 nonaka "ht40_max_pwr_offset c0: %d %d %d, c1: %d %d %d\n", 1467 1.1 nonaka rp->ht40_max_pwr[0] & 0xf, rp->ht40_max_pwr[1] & 0xf, 1468 1.1 nonaka rp->ht40_max_pwr[2] & 0xf, 1469 1.1 nonaka rp->ht40_max_pwr[0] >> 4, rp->ht40_max_pwr[1] >> 4, 1470 1.1 nonaka rp->ht40_max_pwr[2] >> 4); 1471 1.1 nonaka 1472 1.1 nonaka aprint_normal_dev(sc->sc_dev, 1473 1.1 nonaka "ht20_max_pwr_offset c0: %d %d %d, c1: %d %d %d\n", 1474 1.1 nonaka rp->ht20_max_pwr[0] & 0xf, rp->ht20_max_pwr[1] & 0xf, 1475 1.1 nonaka rp->ht20_max_pwr[2] & 0xf, 1476 1.1 nonaka rp->ht20_max_pwr[0] >> 4, rp->ht20_max_pwr[1] >> 4, 1477 1.1 nonaka rp->ht20_max_pwr[2] >> 4); 1478 1.1 nonaka 1479 1.1 nonaka aprint_normal_dev(sc->sc_dev, 1480 1.1 nonaka "xtal_calib %d, tssi %d %d, thermal %d\n", 1481 1.1 nonaka rp->xtal_calib, rp->tssi[0], rp->tssi[1], rp->thermal_meter); 1482 1.1 nonaka 1483 1.1 nonaka aprint_normal_dev(sc->sc_dev, 1484 1.82 christos "rf_opt1 %#x, rf_opt2 %#x, rf_opt3 %#x, rf_opt4 %#x\n", 1485 1.1 nonaka rp->rf_opt1, rp->rf_opt2, rp->rf_opt3, rp->rf_opt4); 1486 1.1 nonaka 1487 1.1 nonaka aprint_normal_dev(sc->sc_dev, 1488 1.82 christos "channnel_plan %d, version %d customer_id %#x\n", 1489 1.1 nonaka rp->channel_plan, rp->version, rp->curstomer_id); 1490 1.1 nonaka } 1491 1.1 nonaka #endif 1492 1.1 nonaka 1493 1.1 nonaka static void 1494 1.1 nonaka urtwn_read_rom(struct urtwn_softc *sc) 1495 1.1 nonaka { 1496 1.1 nonaka struct ieee80211com *ic = &sc->sc_ic; 1497 1.1 nonaka struct r92c_rom *rom = &sc->rom; 1498 1.1 nonaka 1499 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1500 1.1 nonaka 1501 1.12 christos mutex_enter(&sc->sc_write_mtx); 1502 1.12 christos 1503 1.1 nonaka /* Read full ROM image. */ 1504 1.1 nonaka urtwn_efuse_read(sc); 1505 1.1 nonaka #ifdef URTWN_DEBUG 1506 1.1 nonaka if (urtwn_debug & DBG_REG) 1507 1.1 nonaka urtwn_dump_rom(sc, rom); 1508 1.1 nonaka #endif 1509 1.1 nonaka 1510 1.1 nonaka /* XXX Weird but this is what the vendor driver does. */ 1511 1.1 nonaka sc->pa_setting = urtwn_efuse_read_1(sc, 0x1fa); 1512 1.1 nonaka sc->board_type = MS(rom->rf_opt1, R92C_ROM_RF1_BOARD_TYPE); 1513 1.1 nonaka sc->regulatory = MS(rom->rf_opt1, R92C_ROM_RF1_REGULATORY); 1514 1.1 nonaka 1515 1.1 nonaka DPRINTFN(DBG_INIT, 1516 1.75 gson "PA setting=%#jx, board=%#jx, regulatory=%jd", 1517 1.74 gson sc->pa_setting, sc->board_type, sc->regulatory, 0); 1518 1.1 nonaka 1519 1.1 nonaka IEEE80211_ADDR_COPY(ic->ic_myaddr, rom->macaddr); 1520 1.12 christos 1521 1.32 nonaka sc->sc_rf_write = urtwn_r92c_rf_write; 1522 1.32 nonaka sc->sc_power_on = urtwn_r92c_power_on; 1523 1.32 nonaka sc->sc_dma_init = urtwn_r92c_dma_init; 1524 1.32 nonaka 1525 1.32 nonaka mutex_exit(&sc->sc_write_mtx); 1526 1.32 nonaka } 1527 1.32 nonaka 1528 1.32 nonaka static void 1529 1.32 nonaka urtwn_r88e_read_rom(struct urtwn_softc *sc) 1530 1.32 nonaka { 1531 1.32 nonaka struct ieee80211com *ic = &sc->sc_ic; 1532 1.32 nonaka uint8_t *rom = sc->r88e_rom; 1533 1.32 nonaka uint32_t reg; 1534 1.32 nonaka uint16_t addr = 0; 1535 1.32 nonaka uint8_t off, msk, tmp; 1536 1.32 nonaka int i; 1537 1.32 nonaka 1538 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1539 1.32 nonaka 1540 1.32 nonaka mutex_enter(&sc->sc_write_mtx); 1541 1.32 nonaka 1542 1.32 nonaka off = 0; 1543 1.32 nonaka urtwn_efuse_switch_power(sc); 1544 1.32 nonaka 1545 1.32 nonaka /* Read full ROM image. */ 1546 1.32 nonaka memset(&sc->r88e_rom, 0xff, sizeof(sc->r88e_rom)); 1547 1.49 nat while (addr < 4096) { 1548 1.32 nonaka reg = urtwn_efuse_read_1(sc, addr); 1549 1.32 nonaka if (reg == 0xff) 1550 1.32 nonaka break; 1551 1.32 nonaka addr++; 1552 1.32 nonaka if ((reg & 0x1f) == 0x0f) { 1553 1.32 nonaka tmp = (reg & 0xe0) >> 5; 1554 1.32 nonaka reg = urtwn_efuse_read_1(sc, addr); 1555 1.32 nonaka if ((reg & 0x0f) != 0x0f) 1556 1.32 nonaka off = ((reg & 0xf0) >> 1) | tmp; 1557 1.32 nonaka addr++; 1558 1.32 nonaka } else 1559 1.32 nonaka off = reg >> 4; 1560 1.32 nonaka msk = reg & 0xf; 1561 1.32 nonaka for (i = 0; i < 4; i++) { 1562 1.32 nonaka if (msk & (1 << i)) 1563 1.32 nonaka continue; 1564 1.32 nonaka rom[off * 8 + i * 2 + 0] = urtwn_efuse_read_1(sc, addr); 1565 1.32 nonaka addr++; 1566 1.32 nonaka rom[off * 8 + i * 2 + 1] = urtwn_efuse_read_1(sc, addr); 1567 1.32 nonaka addr++; 1568 1.32 nonaka } 1569 1.32 nonaka } 1570 1.32 nonaka #ifdef URTWN_DEBUG 1571 1.32 nonaka if (urtwn_debug & DBG_REG) { 1572 1.32 nonaka } 1573 1.32 nonaka #endif 1574 1.32 nonaka 1575 1.32 nonaka addr = 0x10; 1576 1.32 nonaka for (i = 0; i < 6; i++) 1577 1.32 nonaka sc->cck_tx_pwr[i] = sc->r88e_rom[addr++]; 1578 1.32 nonaka for (i = 0; i < 5; i++) 1579 1.32 nonaka sc->ht40_tx_pwr[i] = sc->r88e_rom[addr++]; 1580 1.32 nonaka sc->bw20_tx_pwr_diff = (sc->r88e_rom[addr] & 0xf0) >> 4; 1581 1.32 nonaka if (sc->bw20_tx_pwr_diff & 0x08) 1582 1.32 nonaka sc->bw20_tx_pwr_diff |= 0xf0; 1583 1.32 nonaka sc->ofdm_tx_pwr_diff = (sc->r88e_rom[addr] & 0xf); 1584 1.32 nonaka if (sc->ofdm_tx_pwr_diff & 0x08) 1585 1.32 nonaka sc->ofdm_tx_pwr_diff |= 0xf0; 1586 1.32 nonaka sc->regulatory = MS(sc->r88e_rom[0xc1], R92C_ROM_RF1_REGULATORY); 1587 1.32 nonaka 1588 1.32 nonaka IEEE80211_ADDR_COPY(ic->ic_myaddr, &sc->r88e_rom[0xd7]); 1589 1.32 nonaka 1590 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_92EU)) { 1591 1.49 nat sc->sc_power_on = urtwn_r92e_power_on; 1592 1.49 nat sc->sc_rf_write = urtwn_r92e_rf_write; 1593 1.49 nat } else { 1594 1.49 nat sc->sc_power_on = urtwn_r88e_power_on; 1595 1.49 nat sc->sc_rf_write = urtwn_r88e_rf_write; 1596 1.49 nat } 1597 1.32 nonaka sc->sc_dma_init = urtwn_r88e_dma_init; 1598 1.32 nonaka 1599 1.12 christos mutex_exit(&sc->sc_write_mtx); 1600 1.1 nonaka } 1601 1.1 nonaka 1602 1.1 nonaka static int 1603 1.1 nonaka urtwn_media_change(struct ifnet *ifp) 1604 1.1 nonaka { 1605 1.1 nonaka int error; 1606 1.1 nonaka 1607 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1608 1.1 nonaka 1609 1.1 nonaka if ((error = ieee80211_media_change(ifp)) != ENETRESET) 1610 1.42 skrll return error; 1611 1.1 nonaka 1612 1.1 nonaka if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 1613 1.1 nonaka (IFF_UP | IFF_RUNNING)) { 1614 1.1 nonaka urtwn_init(ifp); 1615 1.1 nonaka } 1616 1.42 skrll return 0; 1617 1.1 nonaka } 1618 1.1 nonaka 1619 1.1 nonaka /* 1620 1.1 nonaka * Initialize rate adaptation in firmware. 1621 1.1 nonaka */ 1622 1.88 jdolecek static int __noinline 1623 1.1 nonaka urtwn_ra_init(struct urtwn_softc *sc) 1624 1.1 nonaka { 1625 1.1 nonaka static const uint8_t map[] = { 1626 1.1 nonaka 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 1627 1.1 nonaka }; 1628 1.1 nonaka struct ieee80211com *ic = &sc->sc_ic; 1629 1.1 nonaka struct ieee80211_node *ni = ic->ic_bss; 1630 1.1 nonaka struct ieee80211_rateset *rs = &ni->ni_rates; 1631 1.1 nonaka struct r92c_fw_cmd_macid_cfg cmd; 1632 1.1 nonaka uint32_t rates, basicrates; 1633 1.60 thorpej uint32_t rrsr_mask, rrsr_rate; 1634 1.1 nonaka uint8_t mode; 1635 1.22 christos size_t maxrate, maxbasicrate, i, j; 1636 1.22 christos int error; 1637 1.1 nonaka 1638 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1639 1.1 nonaka 1640 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 1641 1.12 christos 1642 1.1 nonaka /* Get normal and basic rates mask. */ 1643 1.49 nat rates = basicrates = 1; 1644 1.1 nonaka maxrate = maxbasicrate = 0; 1645 1.1 nonaka for (i = 0; i < rs->rs_nrates; i++) { 1646 1.1 nonaka /* Convert 802.11 rate to HW rate index. */ 1647 1.22 christos for (j = 0; j < __arraycount(map); j++) { 1648 1.1 nonaka if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == map[j]) { 1649 1.1 nonaka break; 1650 1.1 nonaka } 1651 1.1 nonaka } 1652 1.1 nonaka if (j == __arraycount(map)) { 1653 1.1 nonaka /* Unknown rate, skip. */ 1654 1.1 nonaka continue; 1655 1.1 nonaka } 1656 1.1 nonaka 1657 1.1 nonaka rates |= 1U << j; 1658 1.1 nonaka if (j > maxrate) { 1659 1.1 nonaka maxrate = j; 1660 1.1 nonaka } 1661 1.1 nonaka 1662 1.1 nonaka if (rs->rs_rates[i] & IEEE80211_RATE_BASIC) { 1663 1.1 nonaka basicrates |= 1U << j; 1664 1.1 nonaka if (j > maxbasicrate) { 1665 1.1 nonaka maxbasicrate = j; 1666 1.1 nonaka } 1667 1.1 nonaka } 1668 1.1 nonaka } 1669 1.1 nonaka if (ic->ic_curmode == IEEE80211_MODE_11B) { 1670 1.1 nonaka mode = R92C_RAID_11B; 1671 1.1 nonaka } else { 1672 1.1 nonaka mode = R92C_RAID_11BG; 1673 1.1 nonaka } 1674 1.75 gson DPRINTFN(DBG_INIT, "mode=%#jx", mode, 0, 0, 0); 1675 1.75 gson DPRINTFN(DBG_INIT, "rates=%#jx, basicrates=%#jx, " 1676 1.74 gson "maxrate=%jx, maxbasicrate=%jx", 1677 1.74 gson rates, basicrates, maxrate, maxbasicrate); 1678 1.49 nat 1679 1.49 nat if (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) { 1680 1.49 nat maxbasicrate |= R92C_RATE_SHORTGI; 1681 1.49 nat maxrate |= R92C_RATE_SHORTGI; 1682 1.1 nonaka } 1683 1.1 nonaka 1684 1.1 nonaka /* Set rates mask for group addressed frames. */ 1685 1.60 thorpej cmd.macid = RTWN_MACID_BC | RTWN_MACID_VALID; 1686 1.49 nat if (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) 1687 1.60 thorpej cmd.macid |= RTWN_MACID_SHORTGI; 1688 1.60 thorpej cmd.mask = htole32((mode << 28) | basicrates); 1689 1.1 nonaka error = urtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd)); 1690 1.1 nonaka if (error != 0) { 1691 1.1 nonaka aprint_error_dev(sc->sc_dev, 1692 1.1 nonaka "could not add broadcast station\n"); 1693 1.42 skrll return error; 1694 1.1 nonaka } 1695 1.1 nonaka /* Set initial MRR rate. */ 1696 1.74 gson DPRINTFN(DBG_INIT, "maxbasicrate=%jd", maxbasicrate, 0, 0, 0); 1697 1.60 thorpej urtwn_write_1(sc, R92C_INIDATA_RATE_SEL(RTWN_MACID_BC), maxbasicrate); 1698 1.1 nonaka 1699 1.1 nonaka /* Set rates mask for unicast frames. */ 1700 1.60 thorpej cmd.macid = RTWN_MACID_BSS | RTWN_MACID_VALID; 1701 1.49 nat if (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) 1702 1.60 thorpej cmd.macid |= RTWN_MACID_SHORTGI; 1703 1.60 thorpej cmd.mask = htole32((mode << 28) | rates); 1704 1.1 nonaka error = urtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd)); 1705 1.1 nonaka if (error != 0) { 1706 1.1 nonaka aprint_error_dev(sc->sc_dev, "could not add BSS station\n"); 1707 1.42 skrll return error; 1708 1.1 nonaka } 1709 1.1 nonaka /* Set initial MRR rate. */ 1710 1.74 gson DPRINTFN(DBG_INIT, "maxrate=%jd", maxrate, 0, 0, 0); 1711 1.60 thorpej urtwn_write_1(sc, R92C_INIDATA_RATE_SEL(RTWN_MACID_BSS), maxrate); 1712 1.1 nonaka 1713 1.49 nat rrsr_rate = ic->ic_fixed_rate; 1714 1.49 nat if (rrsr_rate == -1) 1715 1.49 nat rrsr_rate = 11; 1716 1.49 nat 1717 1.49 nat rrsr_mask = 0xffff >> (15 - rrsr_rate); 1718 1.49 nat urtwn_write_2(sc, R92C_RRSR, rrsr_mask); 1719 1.49 nat 1720 1.1 nonaka /* Indicate highest supported rate. */ 1721 1.1 nonaka ni->ni_txrate = rs->rs_nrates - 1; 1722 1.1 nonaka 1723 1.42 skrll return 0; 1724 1.1 nonaka } 1725 1.1 nonaka 1726 1.1 nonaka static int 1727 1.1 nonaka urtwn_get_nettype(struct urtwn_softc *sc) 1728 1.1 nonaka { 1729 1.1 nonaka struct ieee80211com *ic = &sc->sc_ic; 1730 1.1 nonaka int type; 1731 1.1 nonaka 1732 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1733 1.1 nonaka 1734 1.1 nonaka switch (ic->ic_opmode) { 1735 1.1 nonaka case IEEE80211_M_STA: 1736 1.1 nonaka type = R92C_CR_NETTYPE_INFRA; 1737 1.1 nonaka break; 1738 1.1 nonaka 1739 1.1 nonaka case IEEE80211_M_IBSS: 1740 1.1 nonaka type = R92C_CR_NETTYPE_ADHOC; 1741 1.1 nonaka break; 1742 1.1 nonaka 1743 1.1 nonaka default: 1744 1.1 nonaka type = R92C_CR_NETTYPE_NOLINK; 1745 1.1 nonaka break; 1746 1.1 nonaka } 1747 1.1 nonaka 1748 1.42 skrll return type; 1749 1.1 nonaka } 1750 1.1 nonaka 1751 1.1 nonaka static void 1752 1.1 nonaka urtwn_set_nettype0_msr(struct urtwn_softc *sc, uint8_t type) 1753 1.1 nonaka { 1754 1.1 nonaka uint8_t reg; 1755 1.1 nonaka 1756 1.74 gson URTWNHIST_FUNC(); 1757 1.74 gson URTWNHIST_CALLARGS("type=%jd", type, 0, 0, 0); 1758 1.1 nonaka 1759 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 1760 1.12 christos 1761 1.1 nonaka reg = urtwn_read_1(sc, R92C_CR + 2) & 0x0c; 1762 1.1 nonaka urtwn_write_1(sc, R92C_CR + 2, reg | type); 1763 1.1 nonaka } 1764 1.1 nonaka 1765 1.1 nonaka static void 1766 1.1 nonaka urtwn_tsf_sync_enable(struct urtwn_softc *sc) 1767 1.1 nonaka { 1768 1.1 nonaka struct ieee80211_node *ni = sc->sc_ic.ic_bss; 1769 1.1 nonaka uint64_t tsf; 1770 1.1 nonaka 1771 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1772 1.1 nonaka 1773 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 1774 1.12 christos 1775 1.1 nonaka /* Enable TSF synchronization. */ 1776 1.1 nonaka urtwn_write_1(sc, R92C_BCN_CTRL, 1777 1.1 nonaka urtwn_read_1(sc, R92C_BCN_CTRL) & ~R92C_BCN_CTRL_DIS_TSF_UDT0); 1778 1.1 nonaka 1779 1.1 nonaka /* Correct TSF */ 1780 1.1 nonaka urtwn_write_1(sc, R92C_BCN_CTRL, 1781 1.1 nonaka urtwn_read_1(sc, R92C_BCN_CTRL) & ~R92C_BCN_CTRL_EN_BCN); 1782 1.1 nonaka 1783 1.1 nonaka /* Set initial TSF. */ 1784 1.1 nonaka tsf = ni->ni_tstamp.tsf; 1785 1.1 nonaka tsf = le64toh(tsf); 1786 1.1 nonaka tsf = tsf - (tsf % (ni->ni_intval * IEEE80211_DUR_TU)); 1787 1.1 nonaka tsf -= IEEE80211_DUR_TU; 1788 1.1 nonaka urtwn_write_4(sc, R92C_TSFTR + 0, (uint32_t)tsf); 1789 1.1 nonaka urtwn_write_4(sc, R92C_TSFTR + 4, (uint32_t)(tsf >> 32)); 1790 1.1 nonaka 1791 1.1 nonaka urtwn_write_1(sc, R92C_BCN_CTRL, 1792 1.1 nonaka urtwn_read_1(sc, R92C_BCN_CTRL) | R92C_BCN_CTRL_EN_BCN); 1793 1.1 nonaka } 1794 1.1 nonaka 1795 1.1 nonaka static void 1796 1.1 nonaka urtwn_set_led(struct urtwn_softc *sc, int led, int on) 1797 1.1 nonaka { 1798 1.1 nonaka uint8_t reg; 1799 1.1 nonaka 1800 1.74 gson URTWNHIST_FUNC(); 1801 1.74 gson URTWNHIST_CALLARGS("led=%jd, on=%jd", led, on, 0, 0); 1802 1.1 nonaka 1803 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 1804 1.12 christos 1805 1.1 nonaka if (led == URTWN_LED_LINK) { 1806 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_92EU)) { 1807 1.49 nat urtwn_write_1(sc, 0x64, urtwn_read_1(sc, 0x64) & 0xfe); 1808 1.49 nat reg = urtwn_read_1(sc, R92C_LEDCFG1) & R92E_LEDSON; 1809 1.49 nat urtwn_write_1(sc, R92C_LEDCFG1, reg | 1810 1.49 nat (R92C_LEDCFG0_DIS << 1)); 1811 1.49 nat if (on) { 1812 1.49 nat reg = urtwn_read_1(sc, R92C_LEDCFG1) & 1813 1.49 nat R92E_LEDSON; 1814 1.49 nat urtwn_write_1(sc, R92C_LEDCFG1, reg); 1815 1.49 nat } 1816 1.49 nat } else if (ISSET(sc->chip, URTWN_CHIP_88E)) { 1817 1.32 nonaka reg = urtwn_read_1(sc, R92C_LEDCFG2) & 0xf0; 1818 1.32 nonaka urtwn_write_1(sc, R92C_LEDCFG2, reg | 0x60); 1819 1.32 nonaka if (!on) { 1820 1.32 nonaka reg = urtwn_read_1(sc, R92C_LEDCFG2) & 0x90; 1821 1.32 nonaka urtwn_write_1(sc, R92C_LEDCFG2, 1822 1.32 nonaka reg | R92C_LEDCFG0_DIS); 1823 1.32 nonaka reg = urtwn_read_1(sc, R92C_MAC_PINMUX_CFG); 1824 1.32 nonaka urtwn_write_1(sc, R92C_MAC_PINMUX_CFG, 1825 1.32 nonaka reg & 0xfe); 1826 1.32 nonaka } 1827 1.32 nonaka } else { 1828 1.32 nonaka reg = urtwn_read_1(sc, R92C_LEDCFG0) & 0x70; 1829 1.32 nonaka if (!on) { 1830 1.32 nonaka reg |= R92C_LEDCFG0_DIS; 1831 1.32 nonaka } 1832 1.32 nonaka urtwn_write_1(sc, R92C_LEDCFG0, reg); 1833 1.1 nonaka } 1834 1.1 nonaka sc->ledlink = on; /* Save LED state. */ 1835 1.1 nonaka } 1836 1.1 nonaka } 1837 1.1 nonaka 1838 1.1 nonaka static void 1839 1.1 nonaka urtwn_calib_to(void *arg) 1840 1.1 nonaka { 1841 1.1 nonaka struct urtwn_softc *sc = arg; 1842 1.1 nonaka 1843 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1844 1.1 nonaka 1845 1.1 nonaka if (sc->sc_dying) 1846 1.1 nonaka return; 1847 1.1 nonaka 1848 1.1 nonaka /* Do it in a process context. */ 1849 1.1 nonaka urtwn_do_async(sc, urtwn_calib_to_cb, NULL, 0); 1850 1.1 nonaka } 1851 1.1 nonaka 1852 1.1 nonaka /* ARGSUSED */ 1853 1.1 nonaka static void 1854 1.1 nonaka urtwn_calib_to_cb(struct urtwn_softc *sc, void *arg) 1855 1.1 nonaka { 1856 1.1 nonaka struct r92c_fw_cmd_rssi cmd; 1857 1.49 nat struct r92e_fw_cmd_rssi cmde; 1858 1.1 nonaka 1859 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1860 1.1 nonaka 1861 1.1 nonaka if (sc->sc_ic.ic_state != IEEE80211_S_RUN) 1862 1.1 nonaka goto restart_timer; 1863 1.1 nonaka 1864 1.12 christos mutex_enter(&sc->sc_write_mtx); 1865 1.1 nonaka if (sc->avg_pwdb != -1) { 1866 1.1 nonaka /* Indicate Rx signal strength to FW for rate adaptation. */ 1867 1.1 nonaka memset(&cmd, 0, sizeof(cmd)); 1868 1.49 nat memset(&cmde, 0, sizeof(cmde)); 1869 1.1 nonaka cmd.macid = 0; /* BSS. */ 1870 1.49 nat cmde.macid = 0; /* BSS. */ 1871 1.1 nonaka cmd.pwdb = sc->avg_pwdb; 1872 1.49 nat cmde.pwdb = sc->avg_pwdb; 1873 1.74 gson DPRINTFN(DBG_RF, "sending RSSI command avg=%jd", 1874 1.74 gson sc->avg_pwdb, 0, 0, 0); 1875 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_92EU)) { 1876 1.49 nat urtwn_fw_cmd(sc, R92C_CMD_RSSI_SETTING, &cmd, 1877 1.49 nat sizeof(cmd)); 1878 1.49 nat } else { 1879 1.49 nat urtwn_fw_cmd(sc, R92E_CMD_RSSI_REPORT, &cmde, 1880 1.49 nat sizeof(cmde)); 1881 1.49 nat } 1882 1.1 nonaka } 1883 1.1 nonaka 1884 1.1 nonaka /* Do temperature compensation. */ 1885 1.1 nonaka urtwn_temp_calib(sc); 1886 1.12 christos mutex_exit(&sc->sc_write_mtx); 1887 1.1 nonaka 1888 1.1 nonaka restart_timer: 1889 1.1 nonaka if (!sc->sc_dying) { 1890 1.1 nonaka /* Restart calibration timer. */ 1891 1.1 nonaka callout_schedule(&sc->sc_calib_to, hz); 1892 1.1 nonaka } 1893 1.1 nonaka } 1894 1.1 nonaka 1895 1.1 nonaka static void 1896 1.1 nonaka urtwn_next_scan(void *arg) 1897 1.1 nonaka { 1898 1.1 nonaka struct urtwn_softc *sc = arg; 1899 1.16 jmcneill int s; 1900 1.1 nonaka 1901 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1902 1.1 nonaka 1903 1.1 nonaka if (sc->sc_dying) 1904 1.1 nonaka return; 1905 1.1 nonaka 1906 1.16 jmcneill s = splnet(); 1907 1.1 nonaka if (sc->sc_ic.ic_state == IEEE80211_S_SCAN) 1908 1.1 nonaka ieee80211_next_scan(&sc->sc_ic); 1909 1.16 jmcneill splx(s); 1910 1.1 nonaka } 1911 1.1 nonaka 1912 1.26 christos static void 1913 1.26 christos urtwn_newassoc(struct ieee80211_node *ni, int isnew) 1914 1.26 christos { 1915 1.74 gson URTWNHIST_FUNC(); 1916 1.74 gson URTWNHIST_CALLARGS("new node %06jx%06jx", 1917 1.74 gson ni->ni_macaddr[0] << 2 | 1918 1.74 gson ni->ni_macaddr[1] << 1 | 1919 1.74 gson ni->ni_macaddr[2], 1920 1.74 gson ni->ni_macaddr[3] << 2 | 1921 1.74 gson ni->ni_macaddr[4] << 1 | 1922 1.74 gson ni->ni_macaddr[5], 1923 1.74 gson 0, 0); 1924 1.26 christos /* start with lowest Tx rate */ 1925 1.26 christos ni->ni_txrate = 0; 1926 1.26 christos } 1927 1.26 christos 1928 1.1 nonaka static int 1929 1.1 nonaka urtwn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 1930 1.1 nonaka { 1931 1.1 nonaka struct urtwn_softc *sc = ic->ic_ifp->if_softc; 1932 1.1 nonaka struct urtwn_cmd_newstate cmd; 1933 1.1 nonaka 1934 1.74 gson URTWNHIST_FUNC(); 1935 1.74 gson URTWNHIST_CALLARGS("nstate=%jd, arg=%jd", nstate, arg, 0, 0); 1936 1.1 nonaka 1937 1.1 nonaka callout_stop(&sc->sc_scan_to); 1938 1.1 nonaka callout_stop(&sc->sc_calib_to); 1939 1.1 nonaka 1940 1.1 nonaka /* Do it in a process context. */ 1941 1.1 nonaka cmd.state = nstate; 1942 1.1 nonaka cmd.arg = arg; 1943 1.1 nonaka urtwn_do_async(sc, urtwn_newstate_cb, &cmd, sizeof(cmd)); 1944 1.42 skrll return 0; 1945 1.1 nonaka } 1946 1.1 nonaka 1947 1.1 nonaka static void 1948 1.1 nonaka urtwn_newstate_cb(struct urtwn_softc *sc, void *arg) 1949 1.1 nonaka { 1950 1.1 nonaka struct urtwn_cmd_newstate *cmd = arg; 1951 1.1 nonaka struct ieee80211com *ic = &sc->sc_ic; 1952 1.1 nonaka struct ieee80211_node *ni; 1953 1.1 nonaka enum ieee80211_state ostate = ic->ic_state; 1954 1.1 nonaka enum ieee80211_state nstate = cmd->state; 1955 1.1 nonaka uint32_t reg; 1956 1.26 christos uint8_t sifs_time, msr; 1957 1.1 nonaka int s; 1958 1.1 nonaka 1959 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 1960 1.74 gson DPRINTFN(DBG_STM, "%jd->%jd", ostate, nstate, 0, 0); 1961 1.1 nonaka 1962 1.1 nonaka s = splnet(); 1963 1.12 christos mutex_enter(&sc->sc_write_mtx); 1964 1.12 christos 1965 1.12 christos callout_stop(&sc->sc_scan_to); 1966 1.12 christos callout_stop(&sc->sc_calib_to); 1967 1.1 nonaka 1968 1.1 nonaka switch (ostate) { 1969 1.1 nonaka case IEEE80211_S_INIT: 1970 1.1 nonaka break; 1971 1.1 nonaka 1972 1.1 nonaka case IEEE80211_S_SCAN: 1973 1.1 nonaka if (nstate != IEEE80211_S_SCAN) { 1974 1.1 nonaka /* 1975 1.1 nonaka * End of scanning 1976 1.1 nonaka */ 1977 1.1 nonaka /* flush 4-AC Queue after site_survey */ 1978 1.1 nonaka urtwn_write_1(sc, R92C_TXPAUSE, 0x0); 1979 1.1 nonaka 1980 1.1 nonaka /* Allow Rx from our BSSID only. */ 1981 1.1 nonaka urtwn_write_4(sc, R92C_RCR, 1982 1.1 nonaka urtwn_read_4(sc, R92C_RCR) | 1983 1.1 nonaka R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN); 1984 1.1 nonaka } 1985 1.1 nonaka break; 1986 1.7 christos 1987 1.1 nonaka case IEEE80211_S_AUTH: 1988 1.1 nonaka case IEEE80211_S_ASSOC: 1989 1.1 nonaka break; 1990 1.1 nonaka 1991 1.1 nonaka case IEEE80211_S_RUN: 1992 1.1 nonaka /* Turn link LED off. */ 1993 1.1 nonaka urtwn_set_led(sc, URTWN_LED_LINK, 0); 1994 1.1 nonaka 1995 1.1 nonaka /* Set media status to 'No Link'. */ 1996 1.1 nonaka urtwn_set_nettype0_msr(sc, R92C_CR_NETTYPE_NOLINK); 1997 1.1 nonaka 1998 1.1 nonaka /* Stop Rx of data frames. */ 1999 1.1 nonaka urtwn_write_2(sc, R92C_RXFLTMAP2, 0); 2000 1.1 nonaka 2001 1.1 nonaka /* Reset TSF. */ 2002 1.1 nonaka urtwn_write_1(sc, R92C_DUAL_TSF_RST, 0x03); 2003 1.1 nonaka 2004 1.1 nonaka /* Disable TSF synchronization. */ 2005 1.1 nonaka urtwn_write_1(sc, R92C_BCN_CTRL, 2006 1.1 nonaka urtwn_read_1(sc, R92C_BCN_CTRL) | 2007 1.1 nonaka R92C_BCN_CTRL_DIS_TSF_UDT0); 2008 1.1 nonaka 2009 1.1 nonaka /* Back to 20MHz mode */ 2010 1.14 jmcneill urtwn_set_chan(sc, ic->ic_curchan, 2011 1.1 nonaka IEEE80211_HTINFO_2NDCHAN_NONE); 2012 1.1 nonaka 2013 1.1 nonaka if (ic->ic_opmode == IEEE80211_M_IBSS || 2014 1.1 nonaka ic->ic_opmode == IEEE80211_M_HOSTAP) { 2015 1.1 nonaka /* Stop BCN */ 2016 1.1 nonaka urtwn_write_1(sc, R92C_BCN_CTRL, 2017 1.1 nonaka urtwn_read_1(sc, R92C_BCN_CTRL) & 2018 1.1 nonaka ~(R92C_BCN_CTRL_EN_BCN | R92C_BCN_CTRL_TXBCN_RPT)); 2019 1.1 nonaka } 2020 1.1 nonaka 2021 1.1 nonaka /* Reset EDCA parameters. */ 2022 1.1 nonaka urtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002f3217); 2023 1.1 nonaka urtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005e4317); 2024 1.1 nonaka urtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x00105320); 2025 1.1 nonaka urtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a444); 2026 1.1 nonaka 2027 1.1 nonaka /* flush all cam entries */ 2028 1.1 nonaka urtwn_cam_init(sc); 2029 1.1 nonaka break; 2030 1.1 nonaka } 2031 1.1 nonaka 2032 1.1 nonaka switch (nstate) { 2033 1.1 nonaka case IEEE80211_S_INIT: 2034 1.1 nonaka /* Turn link LED off. */ 2035 1.1 nonaka urtwn_set_led(sc, URTWN_LED_LINK, 0); 2036 1.1 nonaka break; 2037 1.1 nonaka 2038 1.1 nonaka case IEEE80211_S_SCAN: 2039 1.1 nonaka if (ostate != IEEE80211_S_SCAN) { 2040 1.1 nonaka /* 2041 1.1 nonaka * Begin of scanning 2042 1.1 nonaka */ 2043 1.1 nonaka 2044 1.1 nonaka /* Set gain for scanning. */ 2045 1.1 nonaka reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0)); 2046 1.1 nonaka reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20); 2047 1.1 nonaka urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg); 2048 1.1 nonaka 2049 1.32 nonaka if (!ISSET(sc->chip, URTWN_CHIP_88E)) { 2050 1.32 nonaka reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1)); 2051 1.32 nonaka reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20); 2052 1.32 nonaka urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg); 2053 1.32 nonaka } 2054 1.1 nonaka 2055 1.1 nonaka /* Set media status to 'No Link'. */ 2056 1.1 nonaka urtwn_set_nettype0_msr(sc, R92C_CR_NETTYPE_NOLINK); 2057 1.1 nonaka 2058 1.1 nonaka /* Allow Rx from any BSSID. */ 2059 1.1 nonaka urtwn_write_4(sc, R92C_RCR, 2060 1.1 nonaka urtwn_read_4(sc, R92C_RCR) & 2061 1.1 nonaka ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN)); 2062 1.1 nonaka 2063 1.1 nonaka /* Stop Rx of data frames. */ 2064 1.1 nonaka urtwn_write_2(sc, R92C_RXFLTMAP2, 0); 2065 1.1 nonaka 2066 1.1 nonaka /* Disable update TSF */ 2067 1.1 nonaka urtwn_write_1(sc, R92C_BCN_CTRL, 2068 1.1 nonaka urtwn_read_1(sc, R92C_BCN_CTRL) | 2069 1.1 nonaka R92C_BCN_CTRL_DIS_TSF_UDT0); 2070 1.1 nonaka } 2071 1.1 nonaka 2072 1.1 nonaka /* Make link LED blink during scan. */ 2073 1.1 nonaka urtwn_set_led(sc, URTWN_LED_LINK, !sc->ledlink); 2074 1.1 nonaka 2075 1.1 nonaka /* Pause AC Tx queues. */ 2076 1.1 nonaka urtwn_write_1(sc, R92C_TXPAUSE, 2077 1.1 nonaka urtwn_read_1(sc, R92C_TXPAUSE) | 0x0f); 2078 1.1 nonaka 2079 1.1 nonaka urtwn_set_chan(sc, ic->ic_curchan, 2080 1.1 nonaka IEEE80211_HTINFO_2NDCHAN_NONE); 2081 1.1 nonaka 2082 1.1 nonaka /* Start periodic scan. */ 2083 1.1 nonaka if (!sc->sc_dying) 2084 1.1 nonaka callout_schedule(&sc->sc_scan_to, hz / 5); 2085 1.1 nonaka break; 2086 1.1 nonaka 2087 1.1 nonaka case IEEE80211_S_AUTH: 2088 1.1 nonaka /* Set initial gain under link. */ 2089 1.1 nonaka reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0)); 2090 1.1 nonaka reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32); 2091 1.1 nonaka urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg); 2092 1.1 nonaka 2093 1.32 nonaka if (!ISSET(sc->chip, URTWN_CHIP_88E)) { 2094 1.32 nonaka reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1)); 2095 1.32 nonaka reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32); 2096 1.32 nonaka urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg); 2097 1.32 nonaka } 2098 1.1 nonaka 2099 1.1 nonaka /* Set media status to 'No Link'. */ 2100 1.1 nonaka urtwn_set_nettype0_msr(sc, R92C_CR_NETTYPE_NOLINK); 2101 1.1 nonaka 2102 1.1 nonaka /* Allow Rx from any BSSID. */ 2103 1.1 nonaka urtwn_write_4(sc, R92C_RCR, 2104 1.1 nonaka urtwn_read_4(sc, R92C_RCR) & 2105 1.1 nonaka ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN)); 2106 1.1 nonaka 2107 1.1 nonaka urtwn_set_chan(sc, ic->ic_curchan, 2108 1.1 nonaka IEEE80211_HTINFO_2NDCHAN_NONE); 2109 1.1 nonaka break; 2110 1.1 nonaka 2111 1.1 nonaka case IEEE80211_S_ASSOC: 2112 1.1 nonaka break; 2113 1.1 nonaka 2114 1.1 nonaka case IEEE80211_S_RUN: 2115 1.1 nonaka ni = ic->ic_bss; 2116 1.1 nonaka 2117 1.1 nonaka /* XXX: Set 20MHz mode */ 2118 1.1 nonaka urtwn_set_chan(sc, ic->ic_curchan, 2119 1.1 nonaka IEEE80211_HTINFO_2NDCHAN_NONE); 2120 1.1 nonaka 2121 1.1 nonaka if (ic->ic_opmode == IEEE80211_M_MONITOR) { 2122 1.1 nonaka /* Back to 20MHz mode */ 2123 1.13 jmcneill urtwn_set_chan(sc, ic->ic_curchan, 2124 1.1 nonaka IEEE80211_HTINFO_2NDCHAN_NONE); 2125 1.1 nonaka 2126 1.19 christos /* Set media status to 'No Link'. */ 2127 1.19 christos urtwn_set_nettype0_msr(sc, R92C_CR_NETTYPE_NOLINK); 2128 1.19 christos 2129 1.1 nonaka /* Enable Rx of data frames. */ 2130 1.1 nonaka urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff); 2131 1.1 nonaka 2132 1.19 christos /* Allow Rx from any BSSID. */ 2133 1.19 christos urtwn_write_4(sc, R92C_RCR, 2134 1.19 christos urtwn_read_4(sc, R92C_RCR) & 2135 1.19 christos ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN)); 2136 1.19 christos 2137 1.19 christos /* Accept Rx data/control/management frames */ 2138 1.19 christos urtwn_write_4(sc, R92C_RCR, 2139 1.19 christos urtwn_read_4(sc, R92C_RCR) | 2140 1.19 christos R92C_RCR_ADF | R92C_RCR_ACF | R92C_RCR_AMF); 2141 1.19 christos 2142 1.1 nonaka /* Turn link LED on. */ 2143 1.1 nonaka urtwn_set_led(sc, URTWN_LED_LINK, 1); 2144 1.1 nonaka break; 2145 1.1 nonaka } 2146 1.1 nonaka 2147 1.1 nonaka /* Set media status to 'Associated'. */ 2148 1.1 nonaka urtwn_set_nettype0_msr(sc, urtwn_get_nettype(sc)); 2149 1.1 nonaka 2150 1.1 nonaka /* Set BSSID. */ 2151 1.1 nonaka urtwn_write_4(sc, R92C_BSSID + 0, LE_READ_4(&ni->ni_bssid[0])); 2152 1.1 nonaka urtwn_write_4(sc, R92C_BSSID + 4, LE_READ_2(&ni->ni_bssid[4])); 2153 1.1 nonaka 2154 1.1 nonaka if (ic->ic_curmode == IEEE80211_MODE_11B) { 2155 1.1 nonaka urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 0); 2156 1.1 nonaka } else { 2157 1.1 nonaka /* 802.11b/g */ 2158 1.1 nonaka urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 3); 2159 1.1 nonaka } 2160 1.1 nonaka 2161 1.1 nonaka /* Enable Rx of data frames. */ 2162 1.1 nonaka urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff); 2163 1.1 nonaka 2164 1.1 nonaka /* Set beacon interval. */ 2165 1.1 nonaka urtwn_write_2(sc, R92C_BCN_INTERVAL, ni->ni_intval); 2166 1.1 nonaka 2167 1.28 christos msr = urtwn_read_1(sc, R92C_MSR); 2168 1.29 christos msr &= R92C_MSR_MASK; 2169 1.26 christos switch (ic->ic_opmode) { 2170 1.26 christos case IEEE80211_M_STA: 2171 1.1 nonaka /* Allow Rx from our BSSID only. */ 2172 1.1 nonaka urtwn_write_4(sc, R92C_RCR, 2173 1.1 nonaka urtwn_read_4(sc, R92C_RCR) | 2174 1.1 nonaka R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN); 2175 1.1 nonaka 2176 1.1 nonaka /* Enable TSF synchronization. */ 2177 1.1 nonaka urtwn_tsf_sync_enable(sc); 2178 1.27 nonaka 2179 1.28 christos msr |= R92C_MSR_INFRA; 2180 1.27 nonaka break; 2181 1.26 christos case IEEE80211_M_HOSTAP: 2182 1.28 christos urtwn_write_2(sc, R92C_BCNTCFG, 0x000f); 2183 1.26 christos 2184 1.28 christos /* Allow Rx from any BSSID. */ 2185 1.28 christos urtwn_write_4(sc, R92C_RCR, 2186 1.28 christos urtwn_read_4(sc, R92C_RCR) & 2187 1.28 christos ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN)); 2188 1.28 christos 2189 1.28 christos /* Reset TSF timer to zero. */ 2190 1.28 christos reg = urtwn_read_4(sc, R92C_TCR); 2191 1.28 christos reg &= ~0x01; 2192 1.28 christos urtwn_write_4(sc, R92C_TCR, reg); 2193 1.28 christos reg |= 0x01; 2194 1.28 christos urtwn_write_4(sc, R92C_TCR, reg); 2195 1.27 nonaka 2196 1.28 christos msr |= R92C_MSR_AP; 2197 1.26 christos break; 2198 1.29 christos default: 2199 1.29 christos msr |= R92C_MSR_ADHOC; 2200 1.29 christos break; 2201 1.28 christos } 2202 1.28 christos urtwn_write_1(sc, R92C_MSR, msr); 2203 1.1 nonaka 2204 1.1 nonaka sifs_time = 10; 2205 1.1 nonaka urtwn_write_1(sc, R92C_SIFS_CCK + 1, sifs_time); 2206 1.1 nonaka urtwn_write_1(sc, R92C_SIFS_OFDM + 1, sifs_time); 2207 1.1 nonaka urtwn_write_1(sc, R92C_SPEC_SIFS + 1, sifs_time); 2208 1.1 nonaka urtwn_write_1(sc, R92C_MAC_SPEC_SIFS + 1, sifs_time); 2209 1.1 nonaka urtwn_write_1(sc, R92C_R2T_SIFS + 1, sifs_time); 2210 1.1 nonaka urtwn_write_1(sc, R92C_T2T_SIFS + 1, sifs_time); 2211 1.1 nonaka 2212 1.57 dholland /* Initialize rate adaptation. */ 2213 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_88E) || 2214 1.49 nat ISSET(sc->chip, URTWN_CHIP_92EU)) 2215 1.32 nonaka ni->ni_txrate = ni->ni_rates.rs_nrates - 1; 2216 1.32 nonaka else 2217 1.32 nonaka urtwn_ra_init(sc); 2218 1.1 nonaka 2219 1.1 nonaka /* Turn link LED on. */ 2220 1.1 nonaka urtwn_set_led(sc, URTWN_LED_LINK, 1); 2221 1.1 nonaka 2222 1.1 nonaka /* Reset average RSSI. */ 2223 1.1 nonaka sc->avg_pwdb = -1; 2224 1.1 nonaka 2225 1.1 nonaka /* Reset temperature calibration state machine. */ 2226 1.1 nonaka sc->thcal_state = 0; 2227 1.1 nonaka sc->thcal_lctemp = 0; 2228 1.1 nonaka 2229 1.1 nonaka /* Start periodic calibration. */ 2230 1.1 nonaka if (!sc->sc_dying) 2231 1.1 nonaka callout_schedule(&sc->sc_calib_to, hz); 2232 1.1 nonaka break; 2233 1.1 nonaka } 2234 1.1 nonaka 2235 1.1 nonaka (*sc->sc_newstate)(ic, nstate, cmd->arg); 2236 1.1 nonaka 2237 1.12 christos mutex_exit(&sc->sc_write_mtx); 2238 1.1 nonaka splx(s); 2239 1.1 nonaka } 2240 1.1 nonaka 2241 1.1 nonaka static int 2242 1.1 nonaka urtwn_wme_update(struct ieee80211com *ic) 2243 1.1 nonaka { 2244 1.1 nonaka struct urtwn_softc *sc = ic->ic_ifp->if_softc; 2245 1.1 nonaka 2246 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 2247 1.1 nonaka 2248 1.1 nonaka /* don't override default WME values if WME is not actually enabled */ 2249 1.1 nonaka if (!(ic->ic_flags & IEEE80211_F_WME)) 2250 1.42 skrll return 0; 2251 1.1 nonaka 2252 1.1 nonaka /* Do it in a process context. */ 2253 1.1 nonaka urtwn_do_async(sc, urtwn_wme_update_cb, NULL, 0); 2254 1.42 skrll return 0; 2255 1.1 nonaka } 2256 1.1 nonaka 2257 1.1 nonaka static void 2258 1.1 nonaka urtwn_wme_update_cb(struct urtwn_softc *sc, void *arg) 2259 1.1 nonaka { 2260 1.1 nonaka static const uint16_t ac2reg[WME_NUM_AC] = { 2261 1.1 nonaka R92C_EDCA_BE_PARAM, 2262 1.1 nonaka R92C_EDCA_BK_PARAM, 2263 1.1 nonaka R92C_EDCA_VI_PARAM, 2264 1.1 nonaka R92C_EDCA_VO_PARAM 2265 1.1 nonaka }; 2266 1.1 nonaka struct ieee80211com *ic = &sc->sc_ic; 2267 1.1 nonaka const struct wmeParams *wmep; 2268 1.1 nonaka int ac, aifs, slottime; 2269 1.1 nonaka int s; 2270 1.1 nonaka 2271 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 2272 1.74 gson DPRINTFN(DBG_STM, "called", 0, 0, 0, 0); 2273 1.1 nonaka 2274 1.1 nonaka s = splnet(); 2275 1.12 christos mutex_enter(&sc->sc_write_mtx); 2276 1.1 nonaka slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; 2277 1.1 nonaka for (ac = 0; ac < WME_NUM_AC; ac++) { 2278 1.1 nonaka wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac]; 2279 1.1 nonaka /* AIFS[AC] = AIFSN[AC] * aSlotTime + aSIFSTime. */ 2280 1.1 nonaka aifs = wmep->wmep_aifsn * slottime + 10; 2281 1.1 nonaka urtwn_write_4(sc, ac2reg[ac], 2282 1.1 nonaka SM(R92C_EDCA_PARAM_TXOP, wmep->wmep_txopLimit) | 2283 1.1 nonaka SM(R92C_EDCA_PARAM_ECWMIN, wmep->wmep_logcwmin) | 2284 1.1 nonaka SM(R92C_EDCA_PARAM_ECWMAX, wmep->wmep_logcwmax) | 2285 1.1 nonaka SM(R92C_EDCA_PARAM_AIFS, aifs)); 2286 1.1 nonaka } 2287 1.12 christos mutex_exit(&sc->sc_write_mtx); 2288 1.1 nonaka splx(s); 2289 1.1 nonaka } 2290 1.1 nonaka 2291 1.1 nonaka static void 2292 1.1 nonaka urtwn_update_avgrssi(struct urtwn_softc *sc, int rate, int8_t rssi) 2293 1.1 nonaka { 2294 1.1 nonaka int pwdb; 2295 1.1 nonaka 2296 1.74 gson URTWNHIST_FUNC(); 2297 1.74 gson URTWNHIST_CALLARGS("rate=%jd, rsst=%jd", rate, rssi, 0, 0); 2298 1.1 nonaka 2299 1.1 nonaka /* Convert antenna signal to percentage. */ 2300 1.1 nonaka if (rssi <= -100 || rssi >= 20) 2301 1.1 nonaka pwdb = 0; 2302 1.1 nonaka else if (rssi >= 0) 2303 1.1 nonaka pwdb = 100; 2304 1.1 nonaka else 2305 1.1 nonaka pwdb = 100 + rssi; 2306 1.32 nonaka if (!ISSET(sc->chip, URTWN_CHIP_88E)) { 2307 1.32 nonaka if (rate <= 3) { 2308 1.32 nonaka /* CCK gain is smaller than OFDM/MCS gain. */ 2309 1.32 nonaka pwdb += 6; 2310 1.32 nonaka if (pwdb > 100) 2311 1.32 nonaka pwdb = 100; 2312 1.32 nonaka if (pwdb <= 14) 2313 1.32 nonaka pwdb -= 4; 2314 1.32 nonaka else if (pwdb <= 26) 2315 1.32 nonaka pwdb -= 8; 2316 1.32 nonaka else if (pwdb <= 34) 2317 1.32 nonaka pwdb -= 6; 2318 1.32 nonaka else if (pwdb <= 42) 2319 1.32 nonaka pwdb -= 2; 2320 1.32 nonaka } 2321 1.1 nonaka } 2322 1.1 nonaka if (sc->avg_pwdb == -1) /* Init. */ 2323 1.1 nonaka sc->avg_pwdb = pwdb; 2324 1.1 nonaka else if (sc->avg_pwdb < pwdb) 2325 1.1 nonaka sc->avg_pwdb = ((sc->avg_pwdb * 19 + pwdb) / 20) + 1; 2326 1.1 nonaka else 2327 1.1 nonaka sc->avg_pwdb = ((sc->avg_pwdb * 19 + pwdb) / 20); 2328 1.1 nonaka 2329 1.74 gson DPRINTFN(DBG_RF, "rate=%jd rssi=%jd PWDB=%jd EMA=%jd", 2330 1.74 gson rate, rssi, pwdb, sc->avg_pwdb); 2331 1.1 nonaka } 2332 1.1 nonaka 2333 1.1 nonaka static int8_t 2334 1.1 nonaka urtwn_get_rssi(struct urtwn_softc *sc, int rate, void *physt) 2335 1.1 nonaka { 2336 1.1 nonaka static const int8_t cckoff[] = { 16, -12, -26, -46 }; 2337 1.1 nonaka struct r92c_rx_phystat *phy; 2338 1.1 nonaka struct r92c_rx_cck *cck; 2339 1.1 nonaka uint8_t rpt; 2340 1.1 nonaka int8_t rssi; 2341 1.1 nonaka 2342 1.74 gson URTWNHIST_FUNC(); 2343 1.74 gson URTWNHIST_CALLARGS("rate=%jd", rate, 0, 0, 0); 2344 1.1 nonaka 2345 1.1 nonaka if (rate <= 3) { 2346 1.1 nonaka cck = (struct r92c_rx_cck *)physt; 2347 1.1 nonaka if (ISSET(sc->sc_flags, URTWN_FLAG_CCK_HIPWR)) { 2348 1.1 nonaka rpt = (cck->agc_rpt >> 5) & 0x3; 2349 1.1 nonaka rssi = (cck->agc_rpt & 0x1f) << 1; 2350 1.1 nonaka } else { 2351 1.1 nonaka rpt = (cck->agc_rpt >> 6) & 0x3; 2352 1.1 nonaka rssi = cck->agc_rpt & 0x3e; 2353 1.1 nonaka } 2354 1.1 nonaka rssi = cckoff[rpt] - rssi; 2355 1.1 nonaka } else { /* OFDM/HT. */ 2356 1.1 nonaka phy = (struct r92c_rx_phystat *)physt; 2357 1.1 nonaka rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 110; 2358 1.1 nonaka } 2359 1.42 skrll return rssi; 2360 1.1 nonaka } 2361 1.1 nonaka 2362 1.32 nonaka static int8_t 2363 1.32 nonaka urtwn_r88e_get_rssi(struct urtwn_softc *sc, int rate, void *physt) 2364 1.32 nonaka { 2365 1.32 nonaka struct r92c_rx_phystat *phy; 2366 1.32 nonaka struct r88e_rx_cck *cck; 2367 1.32 nonaka uint8_t cck_agc_rpt, lna_idx, vga_idx; 2368 1.32 nonaka int8_t rssi; 2369 1.32 nonaka 2370 1.74 gson URTWNHIST_FUNC(); 2371 1.74 gson URTWNHIST_CALLARGS("rate=%jd", rate, 0, 0, 0); 2372 1.32 nonaka 2373 1.32 nonaka rssi = 0; 2374 1.32 nonaka if (rate <= 3) { 2375 1.32 nonaka cck = (struct r88e_rx_cck *)physt; 2376 1.32 nonaka cck_agc_rpt = cck->agc_rpt; 2377 1.32 nonaka lna_idx = (cck_agc_rpt & 0xe0) >> 5; 2378 1.32 nonaka vga_idx = cck_agc_rpt & 0x1f; 2379 1.32 nonaka switch (lna_idx) { 2380 1.32 nonaka case 7: 2381 1.32 nonaka if (vga_idx <= 27) 2382 1.32 nonaka rssi = -100 + 2* (27 - vga_idx); 2383 1.32 nonaka else 2384 1.32 nonaka rssi = -100; 2385 1.32 nonaka break; 2386 1.32 nonaka case 6: 2387 1.32 nonaka rssi = -48 + 2 * (2 - vga_idx); 2388 1.32 nonaka break; 2389 1.32 nonaka case 5: 2390 1.32 nonaka rssi = -42 + 2 * (7 - vga_idx); 2391 1.32 nonaka break; 2392 1.32 nonaka case 4: 2393 1.32 nonaka rssi = -36 + 2 * (7 - vga_idx); 2394 1.32 nonaka break; 2395 1.32 nonaka case 3: 2396 1.32 nonaka rssi = -24 + 2 * (7 - vga_idx); 2397 1.32 nonaka break; 2398 1.32 nonaka case 2: 2399 1.32 nonaka rssi = -12 + 2 * (5 - vga_idx); 2400 1.32 nonaka break; 2401 1.32 nonaka case 1: 2402 1.32 nonaka rssi = 8 - (2 * vga_idx); 2403 1.32 nonaka break; 2404 1.32 nonaka case 0: 2405 1.32 nonaka rssi = 14 - (2 * vga_idx); 2406 1.32 nonaka break; 2407 1.32 nonaka } 2408 1.32 nonaka rssi += 6; 2409 1.32 nonaka } else { /* OFDM/HT. */ 2410 1.32 nonaka phy = (struct r92c_rx_phystat *)physt; 2411 1.32 nonaka rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 110; 2412 1.32 nonaka } 2413 1.42 skrll return rssi; 2414 1.32 nonaka } 2415 1.32 nonaka 2416 1.1 nonaka static void 2417 1.1 nonaka urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen) 2418 1.1 nonaka { 2419 1.1 nonaka struct ieee80211com *ic = &sc->sc_ic; 2420 1.1 nonaka struct ifnet *ifp = ic->ic_ifp; 2421 1.1 nonaka struct ieee80211_frame *wh; 2422 1.1 nonaka struct ieee80211_node *ni; 2423 1.60 thorpej struct r92c_rx_desc_usb *stat; 2424 1.1 nonaka uint32_t rxdw0, rxdw3; 2425 1.1 nonaka struct mbuf *m; 2426 1.1 nonaka uint8_t rate; 2427 1.1 nonaka int8_t rssi = 0; 2428 1.1 nonaka int s, infosz; 2429 1.1 nonaka 2430 1.74 gson URTWNHIST_FUNC(); 2431 1.74 gson URTWNHIST_CALLARGS("buf=%jp, pktlen=%#jd", (uintptr_t)buf, pktlen, 0, 0); 2432 1.1 nonaka 2433 1.60 thorpej stat = (struct r92c_rx_desc_usb *)buf; 2434 1.1 nonaka rxdw0 = le32toh(stat->rxdw0); 2435 1.1 nonaka rxdw3 = le32toh(stat->rxdw3); 2436 1.1 nonaka 2437 1.1 nonaka if (__predict_false(rxdw0 & (R92C_RXDW0_CRCERR | R92C_RXDW0_ICVERR))) { 2438 1.1 nonaka /* 2439 1.1 nonaka * This should not happen since we setup our Rx filter 2440 1.1 nonaka * to not receive these frames. 2441 1.1 nonaka */ 2442 1.74 gson DPRINTFN(DBG_RX, "CRC error", 0, 0, 0, 0); 2443 1.81 thorpej if_statinc(ifp, if_ierrors); 2444 1.1 nonaka return; 2445 1.1 nonaka } 2446 1.19 christos /* 2447 1.19 christos * XXX: This will drop most control packets. Do we really 2448 1.19 christos * want this in IEEE80211_M_MONITOR mode? 2449 1.19 christos */ 2450 1.22 christos // if (__predict_false(pktlen < (int)sizeof(*wh))) { 2451 1.22 christos if (__predict_false(pktlen < (int)sizeof(struct ieee80211_frame_ack))) { 2452 1.74 gson DPRINTFN(DBG_RX, "packet too short %jd", pktlen, 0, 0, 0); 2453 1.1 nonaka ic->ic_stats.is_rx_tooshort++; 2454 1.81 thorpej if_statinc(ifp, if_ierrors); 2455 1.1 nonaka return; 2456 1.1 nonaka } 2457 1.1 nonaka if (__predict_false(pktlen > MCLBYTES)) { 2458 1.74 gson DPRINTFN(DBG_RX, "packet too big %jd", pktlen, 0, 0, 0); 2459 1.81 thorpej if_statinc(ifp, if_ierrors); 2460 1.1 nonaka return; 2461 1.1 nonaka } 2462 1.1 nonaka 2463 1.1 nonaka rate = MS(rxdw3, R92C_RXDW3_RATE); 2464 1.1 nonaka infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8; 2465 1.1 nonaka 2466 1.1 nonaka /* Get RSSI from PHY status descriptor if present. */ 2467 1.1 nonaka if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) { 2468 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_92C)) 2469 1.32 nonaka rssi = urtwn_r88e_get_rssi(sc, rate, &stat[1]); 2470 1.32 nonaka else 2471 1.32 nonaka rssi = urtwn_get_rssi(sc, rate, &stat[1]); 2472 1.1 nonaka /* Update our average RSSI. */ 2473 1.1 nonaka urtwn_update_avgrssi(sc, rate, rssi); 2474 1.1 nonaka } 2475 1.1 nonaka 2476 1.74 gson DPRINTFN(DBG_RX, "Rx frame len=%jd rate=%jd infosz=%jd rssi=%jd", 2477 1.74 gson pktlen, rate, infosz, rssi); 2478 1.1 nonaka 2479 1.1 nonaka MGETHDR(m, M_DONTWAIT, MT_DATA); 2480 1.1 nonaka if (__predict_false(m == NULL)) { 2481 1.1 nonaka aprint_error_dev(sc->sc_dev, "couldn't allocate rx mbuf\n"); 2482 1.1 nonaka ic->ic_stats.is_rx_nobuf++; 2483 1.81 thorpej if_statinc(ifp, if_ierrors); 2484 1.1 nonaka return; 2485 1.1 nonaka } 2486 1.111 riastrad MCLAIM(m, &sc->sc_ec.ec_rx_mowner); 2487 1.1 nonaka if (pktlen > (int)MHLEN) { 2488 1.1 nonaka MCLGET(m, M_DONTWAIT); 2489 1.1 nonaka if (__predict_false(!(m->m_flags & M_EXT))) { 2490 1.1 nonaka aprint_error_dev(sc->sc_dev, 2491 1.1 nonaka "couldn't allocate rx mbuf cluster\n"); 2492 1.1 nonaka m_freem(m); 2493 1.1 nonaka ic->ic_stats.is_rx_nobuf++; 2494 1.81 thorpej if_statinc(ifp, if_ierrors); 2495 1.1 nonaka return; 2496 1.1 nonaka } 2497 1.1 nonaka } 2498 1.1 nonaka 2499 1.1 nonaka /* Finalize mbuf. */ 2500 1.45 ozaki m_set_rcvif(m, ifp); 2501 1.1 nonaka wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz); 2502 1.1 nonaka memcpy(mtod(m, uint8_t *), wh, pktlen); 2503 1.1 nonaka m->m_pkthdr.len = m->m_len = pktlen; 2504 1.1 nonaka 2505 1.1 nonaka s = splnet(); 2506 1.1 nonaka if (__predict_false(sc->sc_drvbpf != NULL)) { 2507 1.1 nonaka struct urtwn_rx_radiotap_header *tap = &sc->sc_rxtap; 2508 1.1 nonaka 2509 1.19 christos tap->wr_flags = 0; 2510 1.1 nonaka if (!(rxdw3 & R92C_RXDW3_HT)) { 2511 1.1 nonaka switch (rate) { 2512 1.1 nonaka /* CCK. */ 2513 1.1 nonaka case 0: tap->wr_rate = 2; break; 2514 1.1 nonaka case 1: tap->wr_rate = 4; break; 2515 1.1 nonaka case 2: tap->wr_rate = 11; break; 2516 1.1 nonaka case 3: tap->wr_rate = 22; break; 2517 1.1 nonaka /* OFDM. */ 2518 1.1 nonaka case 4: tap->wr_rate = 12; break; 2519 1.1 nonaka case 5: tap->wr_rate = 18; break; 2520 1.1 nonaka case 6: tap->wr_rate = 24; break; 2521 1.1 nonaka case 7: tap->wr_rate = 36; break; 2522 1.1 nonaka case 8: tap->wr_rate = 48; break; 2523 1.1 nonaka case 9: tap->wr_rate = 72; break; 2524 1.1 nonaka case 10: tap->wr_rate = 96; break; 2525 1.1 nonaka case 11: tap->wr_rate = 108; break; 2526 1.1 nonaka } 2527 1.1 nonaka } else if (rate >= 12) { /* MCS0~15. */ 2528 1.1 nonaka /* Bit 7 set means HT MCS instead of rate. */ 2529 1.1 nonaka tap->wr_rate = 0x80 | (rate - 12); 2530 1.1 nonaka } 2531 1.1 nonaka tap->wr_dbm_antsignal = rssi; 2532 1.13 jmcneill tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); 2533 1.13 jmcneill tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); 2534 1.1 nonaka 2535 1.59 msaitoh bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m, BPF_D_IN); 2536 1.1 nonaka } 2537 1.1 nonaka 2538 1.1 nonaka ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); 2539 1.1 nonaka 2540 1.1 nonaka /* push the frame up to the 802.11 stack */ 2541 1.1 nonaka ieee80211_input(ic, m, ni, rssi, 0); 2542 1.1 nonaka 2543 1.1 nonaka /* Node is no longer needed. */ 2544 1.1 nonaka ieee80211_free_node(ni); 2545 1.1 nonaka 2546 1.1 nonaka splx(s); 2547 1.1 nonaka } 2548 1.1 nonaka 2549 1.1 nonaka static void 2550 1.42 skrll urtwn_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 2551 1.1 nonaka { 2552 1.1 nonaka struct urtwn_rx_data *data = priv; 2553 1.1 nonaka struct urtwn_softc *sc = data->sc; 2554 1.60 thorpej struct r92c_rx_desc_usb *stat; 2555 1.49 nat size_t pidx = data->pidx; 2556 1.1 nonaka uint32_t rxdw0; 2557 1.1 nonaka uint8_t *buf; 2558 1.115 nat int len, totlen, pktlen, infosz, npkts, pktspacing; 2559 1.1 nonaka 2560 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 2561 1.74 gson DPRINTFN(DBG_RX, "status=%jd", status, 0, 0, 0); 2562 1.1 nonaka 2563 1.49 nat mutex_enter(&sc->sc_rx_mtx); 2564 1.49 nat TAILQ_REMOVE(&sc->rx_free_list[pidx], data, next); 2565 1.49 nat TAILQ_INSERT_TAIL(&sc->rx_free_list[pidx], data, next); 2566 1.49 nat /* Put this Rx buffer back to our free list. */ 2567 1.49 nat mutex_exit(&sc->sc_rx_mtx); 2568 1.49 nat 2569 1.1 nonaka if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 2570 1.1 nonaka if (status == USBD_STALLED) 2571 1.49 nat usbd_clear_endpoint_stall_async(sc->rx_pipe[pidx]); 2572 1.1 nonaka else if (status != USBD_CANCELLED) 2573 1.1 nonaka goto resubmit; 2574 1.1 nonaka return; 2575 1.1 nonaka } 2576 1.1 nonaka usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 2577 1.1 nonaka 2578 1.1 nonaka if (__predict_false(len < (int)sizeof(*stat))) { 2579 1.74 gson DPRINTFN(DBG_RX, "xfer too short %jd", len, 0, 0, 0); 2580 1.1 nonaka goto resubmit; 2581 1.1 nonaka } 2582 1.1 nonaka buf = data->buf; 2583 1.1 nonaka 2584 1.1 nonaka /* Get the number of encapsulated frames. */ 2585 1.60 thorpej stat = (struct r92c_rx_desc_usb *)buf; 2586 1.86 nat if (ISSET(sc->chip, URTWN_CHIP_92EU)) 2587 1.86 nat npkts = MS(le32toh(stat->rxdw2), R92E_RXDW2_PKTCNT); 2588 1.86 nat else 2589 1.86 nat npkts = MS(le32toh(stat->rxdw2), R92C_RXDW2_PKTCNT); 2590 1.74 gson DPRINTFN(DBG_RX, "Rx %jd frames in one chunk", npkts, 0, 0, 0); 2591 1.1 nonaka 2592 1.70 msaitoh if (npkts != 0) 2593 1.70 msaitoh rnd_add_uint32(&sc->rnd_source, npkts); 2594 1.70 msaitoh 2595 1.115 nat if (ISSET(sc->chip, URTWN_CHIP_92EU)) 2596 1.115 nat pktspacing = 8; 2597 1.115 nat else 2598 1.115 nat pktspacing = 128; 2599 1.115 nat 2600 1.1 nonaka /* Process all of them. */ 2601 1.116 nat while (npkts-- > 0 && len > 0) { 2602 1.1 nonaka if (__predict_false(len < (int)sizeof(*stat))) { 2603 1.74 gson DPRINTFN(DBG_RX, "len(%jd) is short than header", 2604 1.74 gson len, 0, 0, 0); 2605 1.1 nonaka break; 2606 1.1 nonaka } 2607 1.60 thorpej stat = (struct r92c_rx_desc_usb *)buf; 2608 1.1 nonaka rxdw0 = le32toh(stat->rxdw0); 2609 1.1 nonaka 2610 1.1 nonaka pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN); 2611 1.1 nonaka if (__predict_false(pktlen == 0)) { 2612 1.74 gson DPRINTFN(DBG_RX, "pktlen is 0 byte", 0, 0, 0, 0); 2613 1.19 christos break; 2614 1.1 nonaka } 2615 1.1 nonaka 2616 1.1 nonaka infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8; 2617 1.1 nonaka 2618 1.1 nonaka /* Make sure everything fits in xfer. */ 2619 1.1 nonaka totlen = sizeof(*stat) + infosz + pktlen; 2620 1.1 nonaka if (__predict_false(totlen > len)) { 2621 1.74 gson DPRINTFN(DBG_RX, "pktlen (%jd+%jd+%jd) > %jd", 2622 1.74 gson (int)sizeof(*stat), infosz, pktlen, len); 2623 1.1 nonaka break; 2624 1.1 nonaka } 2625 1.1 nonaka 2626 1.1 nonaka /* Process 802.11 frame. */ 2627 1.1 nonaka urtwn_rx_frame(sc, buf, pktlen); 2628 1.1 nonaka 2629 1.115 nat totlen = roundup2(totlen, pktspacing); 2630 1.1 nonaka buf += totlen; 2631 1.1 nonaka len -= totlen; 2632 1.1 nonaka } 2633 1.1 nonaka 2634 1.1 nonaka resubmit: 2635 1.1 nonaka /* Setup a new transfer. */ 2636 1.42 skrll usbd_setup_xfer(xfer, data, data->buf, URTWN_RXBUFSZ, 2637 1.42 skrll USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urtwn_rxeof); 2638 1.1 nonaka (void)usbd_transfer(xfer); 2639 1.1 nonaka } 2640 1.1 nonaka 2641 1.1 nonaka static void 2642 1.93 yamt urtwn_put_tx_data(struct urtwn_softc *sc, struct urtwn_tx_data *data) 2643 1.93 yamt { 2644 1.93 yamt size_t pidx = data->pidx; 2645 1.93 yamt 2646 1.93 yamt mutex_enter(&sc->sc_tx_mtx); 2647 1.93 yamt /* Put this Tx buffer back to our free list. */ 2648 1.93 yamt TAILQ_INSERT_TAIL(&sc->tx_free_list[pidx], data, next); 2649 1.93 yamt mutex_exit(&sc->sc_tx_mtx); 2650 1.93 yamt } 2651 1.93 yamt 2652 1.93 yamt static void 2653 1.42 skrll urtwn_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 2654 1.1 nonaka { 2655 1.1 nonaka struct urtwn_tx_data *data = priv; 2656 1.1 nonaka struct urtwn_softc *sc = data->sc; 2657 1.1 nonaka struct ifnet *ifp = &sc->sc_if; 2658 1.42 skrll size_t pidx = data->pidx; 2659 1.1 nonaka int s; 2660 1.1 nonaka 2661 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 2662 1.74 gson DPRINTFN(DBG_TX, "status=%jd", status, 0, 0, 0); 2663 1.1 nonaka 2664 1.93 yamt urtwn_put_tx_data(sc, data); 2665 1.1 nonaka 2666 1.16 jmcneill s = splnet(); 2667 1.16 jmcneill sc->tx_timer = 0; 2668 1.16 jmcneill ifp->if_flags &= ~IFF_OACTIVE; 2669 1.16 jmcneill 2670 1.1 nonaka if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 2671 1.1 nonaka if (status != USBD_NOT_STARTED && status != USBD_CANCELLED) { 2672 1.42 skrll if (status == USBD_STALLED) { 2673 1.42 skrll struct usbd_pipe *pipe = sc->tx_pipe[pidx]; 2674 1.20 christos usbd_clear_endpoint_stall_async(pipe); 2675 1.42 skrll } 2676 1.105 mlelstv device_printf(sc->sc_dev, "transmit failed, %s\n", 2677 1.111 riastrad usbd_errstr(status)); 2678 1.81 thorpej if_statinc(ifp, if_oerrors); 2679 1.1 nonaka } 2680 1.16 jmcneill splx(s); 2681 1.1 nonaka return; 2682 1.1 nonaka } 2683 1.1 nonaka 2684 1.81 thorpej if_statinc(ifp, if_opackets); 2685 1.16 jmcneill urtwn_start(ifp); 2686 1.49 nat splx(s); 2687 1.1 nonaka 2688 1.1 nonaka } 2689 1.1 nonaka 2690 1.1 nonaka static int 2691 1.12 christos urtwn_tx(struct urtwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 2692 1.12 christos struct urtwn_tx_data *data) 2693 1.1 nonaka { 2694 1.1 nonaka struct ieee80211com *ic = &sc->sc_ic; 2695 1.1 nonaka struct ieee80211_frame *wh; 2696 1.1 nonaka struct ieee80211_key *k = NULL; 2697 1.60 thorpej struct r92c_tx_desc_usb *txd; 2698 1.49 nat size_t i, padsize, xferlen, txd_len; 2699 1.1 nonaka uint16_t seq, sum; 2700 1.42 skrll uint8_t raid, type, tid; 2701 1.22 christos int s, hasqos, error; 2702 1.1 nonaka 2703 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 2704 1.1 nonaka 2705 1.1 nonaka wh = mtod(m, struct ieee80211_frame *); 2706 1.1 nonaka type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 2707 1.49 nat txd_len = sizeof(*txd); 2708 1.49 nat 2709 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_92EU)) 2710 1.49 nat txd_len = 32; 2711 1.1 nonaka 2712 1.1 nonaka if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 2713 1.1 nonaka k = ieee80211_crypto_encap(ic, ni, m); 2714 1.93 yamt if (k == NULL) { 2715 1.93 yamt urtwn_put_tx_data(sc, data); 2716 1.95 nat m_free(m); 2717 1.12 christos return ENOBUFS; 2718 1.93 yamt } 2719 1.12 christos 2720 1.1 nonaka /* packet header may have moved, reset our local pointer */ 2721 1.1 nonaka wh = mtod(m, struct ieee80211_frame *); 2722 1.1 nonaka } 2723 1.1 nonaka 2724 1.1 nonaka if (__predict_false(sc->sc_drvbpf != NULL)) { 2725 1.1 nonaka struct urtwn_tx_radiotap_header *tap = &sc->sc_txtap; 2726 1.1 nonaka 2727 1.1 nonaka tap->wt_flags = 0; 2728 1.14 jmcneill tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); 2729 1.14 jmcneill tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); 2730 1.1 nonaka if (wh->i_fc[1] & IEEE80211_FC1_WEP) 2731 1.1 nonaka tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; 2732 1.1 nonaka 2733 1.19 christos /* XXX: set tap->wt_rate? */ 2734 1.19 christos 2735 1.59 msaitoh bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m, BPF_D_OUT); 2736 1.1 nonaka } 2737 1.1 nonaka 2738 1.42 skrll /* non-qos data frames */ 2739 1.42 skrll tid = R92C_TXDW1_QSEL_BE; 2740 1.23 christos if ((hasqos = ieee80211_has_qos(wh))) { 2741 1.1 nonaka /* data frames in 11n mode */ 2742 1.1 nonaka struct ieee80211_qosframe *qwh = (void *)wh; 2743 1.1 nonaka tid = qwh->i_qos[0] & IEEE80211_QOS_TID; 2744 1.1 nonaka } else if (type != IEEE80211_FC0_TYPE_DATA) { 2745 1.42 skrll tid = R92C_TXDW1_QSEL_MGNT; 2746 1.1 nonaka } 2747 1.1 nonaka 2748 1.49 nat if (((txd_len + m->m_pkthdr.len) % 64) == 0) /* XXX: 64 */ 2749 1.1 nonaka padsize = 8; 2750 1.1 nonaka else 2751 1.1 nonaka padsize = 0; 2752 1.1 nonaka 2753 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_92EU)) 2754 1.49 nat padsize = 0; 2755 1.49 nat 2756 1.1 nonaka /* Fill Tx descriptor. */ 2757 1.60 thorpej txd = (struct r92c_tx_desc_usb *)data->buf; 2758 1.49 nat memset(txd, 0, txd_len + padsize); 2759 1.1 nonaka 2760 1.1 nonaka txd->txdw0 |= htole32( 2761 1.1 nonaka SM(R92C_TXDW0_PKTLEN, m->m_pkthdr.len) | 2762 1.49 nat SM(R92C_TXDW0_OFFSET, txd_len)); 2763 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_92EU)) { 2764 1.49 nat txd->txdw0 |= htole32( 2765 1.49 nat R92C_TXDW0_OWN | R92C_TXDW0_FSG | R92C_TXDW0_LSG); 2766 1.49 nat } 2767 1.1 nonaka 2768 1.1 nonaka if (IEEE80211_IS_MULTICAST(wh->i_addr1)) 2769 1.1 nonaka txd->txdw0 |= htole32(R92C_TXDW0_BMCAST); 2770 1.1 nonaka 2771 1.1 nonaka /* fix pad field */ 2772 1.1 nonaka if (padsize > 0) { 2773 1.74 gson DPRINTFN(DBG_TX, "padding: size=%jd", padsize, 0, 0, 0); 2774 1.1 nonaka txd->txdw1 |= htole32(SM(R92C_TXDW1_PKTOFF, (padsize / 8))); 2775 1.1 nonaka } 2776 1.1 nonaka 2777 1.1 nonaka if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 2778 1.1 nonaka type == IEEE80211_FC0_TYPE_DATA) { 2779 1.1 nonaka if (ic->ic_curmode == IEEE80211_MODE_11B) 2780 1.1 nonaka raid = R92C_RAID_11B; 2781 1.1 nonaka else 2782 1.1 nonaka raid = R92C_RAID_11BG; 2783 1.74 gson DPRINTFN(DBG_TX, "data packet: tid=%jd, raid=%jd", 2784 1.74 gson tid, raid, 0, 0); 2785 1.1 nonaka 2786 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_92C)) { 2787 1.32 nonaka txd->txdw1 |= htole32( 2788 1.60 thorpej SM(R88E_TXDW1_MACID, RTWN_MACID_BSS) | 2789 1.32 nonaka SM(R92C_TXDW1_QSEL, tid) | 2790 1.32 nonaka SM(R92C_TXDW1_RAID, raid) | 2791 1.32 nonaka R92C_TXDW1_AGGBK); 2792 1.32 nonaka } else 2793 1.32 nonaka txd->txdw1 |= htole32( 2794 1.60 thorpej SM(R92C_TXDW1_MACID, RTWN_MACID_BSS) | 2795 1.32 nonaka SM(R92C_TXDW1_QSEL, tid) | 2796 1.32 nonaka SM(R92C_TXDW1_RAID, raid) | 2797 1.32 nonaka R92C_TXDW1_AGGBK); 2798 1.1 nonaka 2799 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_88E)) 2800 1.49 nat txd->txdw2 |= htole32(R88E_TXDW2_AGGBK); 2801 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_92EU)) 2802 1.49 nat txd->txdw3 |= htole32(R92E_TXDW3_AGGBK); 2803 1.49 nat 2804 1.1 nonaka if (hasqos) { 2805 1.1 nonaka txd->txdw4 |= htole32(R92C_TXDW4_QOS); 2806 1.1 nonaka } 2807 1.1 nonaka 2808 1.1 nonaka if (ic->ic_flags & IEEE80211_F_USEPROT) { 2809 1.1 nonaka /* for 11g */ 2810 1.1 nonaka if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 2811 1.1 nonaka txd->txdw4 |= htole32(R92C_TXDW4_CTS2SELF | 2812 1.1 nonaka R92C_TXDW4_HWRTSEN); 2813 1.1 nonaka } else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) { 2814 1.1 nonaka txd->txdw4 |= htole32(R92C_TXDW4_RTSEN | 2815 1.1 nonaka R92C_TXDW4_HWRTSEN); 2816 1.1 nonaka } 2817 1.1 nonaka } 2818 1.1 nonaka /* Send RTS at OFDM24. */ 2819 1.1 nonaka txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, 8)); 2820 1.1 nonaka txd->txdw5 |= htole32(0x0001ff00); 2821 1.1 nonaka /* Send data at OFDM54. */ 2822 1.32 nonaka if (ISSET(sc->chip, URTWN_CHIP_88E)) 2823 1.32 nonaka txd->txdw5 |= htole32(0x13 & 0x3f); 2824 1.32 nonaka else 2825 1.32 nonaka txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11)); 2826 1.1 nonaka } else if (type == IEEE80211_FC0_TYPE_MGT) { 2827 1.74 gson DPRINTFN(DBG_TX, "mgmt packet", 0, 0, 0, 0); 2828 1.1 nonaka txd->txdw1 |= htole32( 2829 1.60 thorpej SM(R92C_TXDW1_MACID, RTWN_MACID_BSS) | 2830 1.1 nonaka SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT) | 2831 1.1 nonaka SM(R92C_TXDW1_RAID, R92C_RAID_11B)); 2832 1.1 nonaka 2833 1.1 nonaka /* Force CCK1. */ 2834 1.1 nonaka txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE); 2835 1.1 nonaka /* Use 1Mbps */ 2836 1.1 nonaka txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 0)); 2837 1.1 nonaka } else { 2838 1.1 nonaka /* broadcast or multicast packets */ 2839 1.74 gson DPRINTFN(DBG_TX, "bc or mc packet", 0, 0, 0, 0); 2840 1.1 nonaka txd->txdw1 |= htole32( 2841 1.60 thorpej SM(R92C_TXDW1_MACID, RTWN_MACID_BC) | 2842 1.1 nonaka SM(R92C_TXDW1_RAID, R92C_RAID_11B)); 2843 1.1 nonaka 2844 1.1 nonaka /* Force CCK1. */ 2845 1.1 nonaka txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE); 2846 1.1 nonaka /* Use 1Mbps */ 2847 1.1 nonaka txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 0)); 2848 1.1 nonaka } 2849 1.1 nonaka /* Set sequence number */ 2850 1.1 nonaka seq = LE_READ_2(&wh->i_seq[0]) >> IEEE80211_SEQ_SEQ_SHIFT; 2851 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_92EU)) { 2852 1.49 nat txd->txdseq |= htole16(seq); 2853 1.1 nonaka 2854 1.49 nat if (!hasqos) { 2855 1.49 nat /* Use HW sequence numbering for non-QoS frames. */ 2856 1.49 nat txd->txdw4 |= htole32(R92C_TXDW4_HWSEQ); 2857 1.49 nat txd->txdseq |= htole16(R92C_HWSEQ_EN); 2858 1.49 nat } 2859 1.49 nat } else { 2860 1.49 nat txd->txdseq2 |= htole16((seq & R92E_HWSEQ_MASK) << 2861 1.49 nat R92E_HWSEQ_SHIFT); 2862 1.49 nat if (!hasqos) { 2863 1.49 nat /* Use HW sequence numbering for non-QoS frames. */ 2864 1.49 nat txd->txdw4 |= htole32(R92C_TXDW4_HWSEQ); 2865 1.49 nat txd->txdw7 |= htole16(R92C_HWSEQ_EN); 2866 1.49 nat } 2867 1.1 nonaka } 2868 1.1 nonaka 2869 1.1 nonaka /* Compute Tx descriptor checksum. */ 2870 1.1 nonaka sum = 0; 2871 1.49 nat for (i = 0; i < R92C_TXDESC_SUMSIZE / 2; i++) 2872 1.1 nonaka sum ^= ((uint16_t *)txd)[i]; 2873 1.1 nonaka txd->txdsum = sum; /* NB: already little endian. */ 2874 1.1 nonaka 2875 1.49 nat xferlen = txd_len + m->m_pkthdr.len + padsize; 2876 1.49 nat m_copydata(m, 0, m->m_pkthdr.len, (char *)&txd[0] + txd_len + padsize); 2877 1.1 nonaka 2878 1.1 nonaka s = splnet(); 2879 1.42 skrll usbd_setup_xfer(data->xfer, data, data->buf, xferlen, 2880 1.42 skrll USBD_FORCE_SHORT_XFER, URTWN_TX_TIMEOUT, 2881 1.1 nonaka urtwn_txeof); 2882 1.1 nonaka error = usbd_transfer(data->xfer); 2883 1.1 nonaka if (__predict_false(error != USBD_NORMAL_COMPLETION && 2884 1.1 nonaka error != USBD_IN_PROGRESS)) { 2885 1.1 nonaka splx(s); 2886 1.74 gson DPRINTFN(DBG_TX, "transfer failed %jd", error, 0, 0, 0); 2887 1.12 christos return error; 2888 1.1 nonaka } 2889 1.1 nonaka splx(s); 2890 1.12 christos return 0; 2891 1.1 nonaka } 2892 1.1 nonaka 2893 1.42 skrll struct urtwn_tx_data * 2894 1.42 skrll urtwn_get_tx_data(struct urtwn_softc *sc, size_t pidx) 2895 1.42 skrll { 2896 1.42 skrll struct urtwn_tx_data *data = NULL; 2897 1.42 skrll 2898 1.42 skrll mutex_enter(&sc->sc_tx_mtx); 2899 1.42 skrll if (!TAILQ_EMPTY(&sc->tx_free_list[pidx])) { 2900 1.42 skrll data = TAILQ_FIRST(&sc->tx_free_list[pidx]); 2901 1.42 skrll TAILQ_REMOVE(&sc->tx_free_list[pidx], data, next); 2902 1.42 skrll } 2903 1.42 skrll mutex_exit(&sc->sc_tx_mtx); 2904 1.42 skrll 2905 1.42 skrll return data; 2906 1.42 skrll } 2907 1.42 skrll 2908 1.1 nonaka static void 2909 1.1 nonaka urtwn_start(struct ifnet *ifp) 2910 1.1 nonaka { 2911 1.1 nonaka struct urtwn_softc *sc = ifp->if_softc; 2912 1.1 nonaka struct ieee80211com *ic = &sc->sc_ic; 2913 1.12 christos struct urtwn_tx_data *data; 2914 1.1 nonaka struct ether_header *eh; 2915 1.1 nonaka struct ieee80211_node *ni; 2916 1.1 nonaka struct mbuf *m; 2917 1.1 nonaka 2918 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 2919 1.1 nonaka 2920 1.1 nonaka if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 2921 1.1 nonaka return; 2922 1.1 nonaka 2923 1.12 christos data = NULL; 2924 1.1 nonaka for (;;) { 2925 1.42 skrll /* Send pending management frames first. */ 2926 1.42 skrll IF_POLL(&ic->ic_mgtq, m); 2927 1.42 skrll if (m != NULL) { 2928 1.42 skrll /* Use AC_VO for management frames. */ 2929 1.17 jmcneill 2930 1.42 skrll data = urtwn_get_tx_data(sc, sc->ac2idx[WME_AC_VO]); 2931 1.1 nonaka 2932 1.42 skrll if (data == NULL) { 2933 1.42 skrll ifp->if_flags |= IFF_OACTIVE; 2934 1.74 gson DPRINTFN(DBG_TX, "empty tx_free_list", 2935 1.74 gson 0, 0, 0, 0); 2936 1.42 skrll return; 2937 1.42 skrll } 2938 1.42 skrll IF_DEQUEUE(&ic->ic_mgtq, m); 2939 1.43 ozaki ni = M_GETCTX(m, struct ieee80211_node *); 2940 1.44 ozaki M_CLEARCTX(m); 2941 1.1 nonaka goto sendit; 2942 1.1 nonaka } 2943 1.1 nonaka if (ic->ic_state != IEEE80211_S_RUN) 2944 1.1 nonaka break; 2945 1.1 nonaka 2946 1.1 nonaka /* Encapsulate and send data frames. */ 2947 1.42 skrll IFQ_POLL(&ifp->if_snd, m); 2948 1.1 nonaka if (m == NULL) 2949 1.1 nonaka break; 2950 1.12 christos 2951 1.42 skrll struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); 2952 1.42 skrll uint8_t type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 2953 1.42 skrll uint8_t qid = WME_AC_BE; 2954 1.42 skrll if (ieee80211_has_qos(wh)) { 2955 1.42 skrll /* data frames in 11n mode */ 2956 1.42 skrll struct ieee80211_qosframe *qwh = (void *)wh; 2957 1.42 skrll uint8_t tid = qwh->i_qos[0] & IEEE80211_QOS_TID; 2958 1.42 skrll qid = TID_TO_WME_AC(tid); 2959 1.42 skrll } else if (type != IEEE80211_FC0_TYPE_DATA) { 2960 1.42 skrll qid = WME_AC_VO; 2961 1.42 skrll } 2962 1.42 skrll data = urtwn_get_tx_data(sc, sc->ac2idx[qid]); 2963 1.42 skrll 2964 1.42 skrll if (data == NULL) { 2965 1.42 skrll ifp->if_flags |= IFF_OACTIVE; 2966 1.74 gson DPRINTFN(DBG_TX, "empty tx_free_list", 0, 0, 0, 0); 2967 1.42 skrll return; 2968 1.42 skrll } 2969 1.42 skrll IFQ_DEQUEUE(&ifp->if_snd, m); 2970 1.42 skrll 2971 1.1 nonaka if (m->m_len < (int)sizeof(*eh) && 2972 1.1 nonaka (m = m_pullup(m, sizeof(*eh))) == NULL) { 2973 1.94 mrg device_printf(sc->sc_dev, "m_pullup failed\n"); 2974 1.81 thorpej if_statinc(ifp, if_oerrors); 2975 1.93 yamt urtwn_put_tx_data(sc, data); 2976 1.95 nat m_freem(m); 2977 1.1 nonaka continue; 2978 1.1 nonaka } 2979 1.1 nonaka eh = mtod(m, struct ether_header *); 2980 1.1 nonaka ni = ieee80211_find_txnode(ic, eh->ether_dhost); 2981 1.1 nonaka if (ni == NULL) { 2982 1.94 mrg device_printf(sc->sc_dev, 2983 1.94 mrg "unable to find transmit node\n"); 2984 1.81 thorpej if_statinc(ifp, if_oerrors); 2985 1.93 yamt urtwn_put_tx_data(sc, data); 2986 1.95 nat m_freem(m); 2987 1.1 nonaka continue; 2988 1.1 nonaka } 2989 1.1 nonaka 2990 1.59 msaitoh bpf_mtap(ifp, m, BPF_D_OUT); 2991 1.1 nonaka 2992 1.1 nonaka if ((m = ieee80211_encap(ic, m, ni)) == NULL) { 2993 1.1 nonaka ieee80211_free_node(ni); 2994 1.94 mrg device_printf(sc->sc_dev, 2995 1.94 mrg "unable to encapsulate packet\n"); 2996 1.81 thorpej if_statinc(ifp, if_oerrors); 2997 1.93 yamt urtwn_put_tx_data(sc, data); 2998 1.95 nat m_freem(m); 2999 1.1 nonaka continue; 3000 1.1 nonaka } 3001 1.1 nonaka sendit: 3002 1.59 msaitoh bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT); 3003 1.1 nonaka 3004 1.12 christos if (urtwn_tx(sc, m, ni, data) != 0) { 3005 1.12 christos m_freem(m); 3006 1.1 nonaka ieee80211_free_node(ni); 3007 1.94 mrg device_printf(sc->sc_dev, 3008 1.94 mrg "unable to transmit packet\n"); 3009 1.81 thorpej if_statinc(ifp, if_oerrors); 3010 1.114 nat urtwn_put_tx_data(sc, data); 3011 1.1 nonaka continue; 3012 1.1 nonaka } 3013 1.12 christos m_freem(m); 3014 1.12 christos ieee80211_free_node(ni); 3015 1.1 nonaka sc->tx_timer = 5; 3016 1.1 nonaka ifp->if_timer = 1; 3017 1.1 nonaka } 3018 1.1 nonaka } 3019 1.1 nonaka 3020 1.1 nonaka static void 3021 1.1 nonaka urtwn_watchdog(struct ifnet *ifp) 3022 1.1 nonaka { 3023 1.1 nonaka struct urtwn_softc *sc = ifp->if_softc; 3024 1.1 nonaka 3025 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 3026 1.1 nonaka 3027 1.1 nonaka ifp->if_timer = 0; 3028 1.1 nonaka 3029 1.1 nonaka if (sc->tx_timer > 0) { 3030 1.1 nonaka if (--sc->tx_timer == 0) { 3031 1.94 mrg device_printf(sc->sc_dev, "device timeout\n"); 3032 1.1 nonaka /* urtwn_init(ifp); XXX needs a process context! */ 3033 1.81 thorpej if_statinc(ifp, if_oerrors); 3034 1.1 nonaka return; 3035 1.1 nonaka } 3036 1.1 nonaka ifp->if_timer = 1; 3037 1.1 nonaka } 3038 1.1 nonaka ieee80211_watchdog(&sc->sc_ic); 3039 1.1 nonaka } 3040 1.1 nonaka 3041 1.1 nonaka static int 3042 1.1 nonaka urtwn_ioctl(struct ifnet *ifp, u_long cmd, void *data) 3043 1.1 nonaka { 3044 1.1 nonaka struct urtwn_softc *sc = ifp->if_softc; 3045 1.1 nonaka struct ieee80211com *ic = &sc->sc_ic; 3046 1.1 nonaka int s, error = 0; 3047 1.1 nonaka 3048 1.74 gson URTWNHIST_FUNC(); 3049 1.83 christos URTWNHIST_CALLARGS("cmd=0x%08jx, data=%#jx", cmd, (uintptr_t)data, 3050 1.74 gson 0, 0); 3051 1.1 nonaka 3052 1.1 nonaka s = splnet(); 3053 1.1 nonaka 3054 1.1 nonaka switch (cmd) { 3055 1.1 nonaka case SIOCSIFFLAGS: 3056 1.1 nonaka if ((error = ifioctl_common(ifp, cmd, data)) != 0) 3057 1.1 nonaka break; 3058 1.12 christos switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { 3059 1.12 christos case IFF_UP | IFF_RUNNING: 3060 1.1 nonaka break; 3061 1.1 nonaka case IFF_UP: 3062 1.1 nonaka urtwn_init(ifp); 3063 1.1 nonaka break; 3064 1.1 nonaka case IFF_RUNNING: 3065 1.1 nonaka urtwn_stop(ifp, 1); 3066 1.1 nonaka break; 3067 1.1 nonaka case 0: 3068 1.1 nonaka break; 3069 1.1 nonaka } 3070 1.1 nonaka break; 3071 1.1 nonaka 3072 1.1 nonaka case SIOCADDMULTI: 3073 1.1 nonaka case SIOCDELMULTI: 3074 1.1 nonaka if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 3075 1.1 nonaka /* setup multicast filter, etc */ 3076 1.1 nonaka error = 0; 3077 1.1 nonaka } 3078 1.1 nonaka break; 3079 1.1 nonaka 3080 1.69 christos case SIOCS80211CHANNEL: 3081 1.69 christos /* 3082 1.69 christos * This allows for fast channel switching in monitor mode 3083 1.69 christos * (used by kismet). In IBSS mode, we must explicitly reset 3084 1.69 christos * the interface to generate a new beacon frame. 3085 1.69 christos */ 3086 1.69 christos error = ieee80211_ioctl(ic, cmd, data); 3087 1.69 christos if (error == ENETRESET && 3088 1.69 christos ic->ic_opmode == IEEE80211_M_MONITOR) { 3089 1.69 christos urtwn_set_chan(sc, ic->ic_curchan, 3090 1.69 christos IEEE80211_HTINFO_2NDCHAN_NONE); 3091 1.69 christos error = 0; 3092 1.69 christos } 3093 1.69 christos break; 3094 1.69 christos 3095 1.1 nonaka default: 3096 1.1 nonaka error = ieee80211_ioctl(ic, cmd, data); 3097 1.1 nonaka break; 3098 1.1 nonaka } 3099 1.1 nonaka if (error == ENETRESET) { 3100 1.1 nonaka if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 3101 1.16 jmcneill (IFF_UP | IFF_RUNNING) && 3102 1.16 jmcneill ic->ic_roaming != IEEE80211_ROAMING_MANUAL) { 3103 1.1 nonaka urtwn_init(ifp); 3104 1.1 nonaka } 3105 1.1 nonaka error = 0; 3106 1.1 nonaka } 3107 1.1 nonaka 3108 1.1 nonaka splx(s); 3109 1.1 nonaka 3110 1.42 skrll return error; 3111 1.1 nonaka } 3112 1.1 nonaka 3113 1.32 nonaka static __inline int 3114 1.32 nonaka urtwn_power_on(struct urtwn_softc *sc) 3115 1.32 nonaka { 3116 1.32 nonaka 3117 1.32 nonaka return sc->sc_power_on(sc); 3118 1.32 nonaka } 3119 1.32 nonaka 3120 1.1 nonaka static int 3121 1.32 nonaka urtwn_r92c_power_on(struct urtwn_softc *sc) 3122 1.1 nonaka { 3123 1.1 nonaka uint32_t reg; 3124 1.1 nonaka int ntries; 3125 1.1 nonaka 3126 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 3127 1.1 nonaka 3128 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 3129 1.12 christos 3130 1.1 nonaka /* Wait for autoload done bit. */ 3131 1.1 nonaka for (ntries = 0; ntries < 1000; ntries++) { 3132 1.1 nonaka if (urtwn_read_1(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_PFM_ALDN) 3133 1.1 nonaka break; 3134 1.1 nonaka DELAY(5); 3135 1.1 nonaka } 3136 1.1 nonaka if (ntries == 1000) { 3137 1.1 nonaka aprint_error_dev(sc->sc_dev, 3138 1.1 nonaka "timeout waiting for chip autoload\n"); 3139 1.42 skrll return ETIMEDOUT; 3140 1.1 nonaka } 3141 1.1 nonaka 3142 1.1 nonaka /* Unlock ISO/CLK/Power control register. */ 3143 1.1 nonaka urtwn_write_1(sc, R92C_RSV_CTRL, 0); 3144 1.100 nat DELAY(5); 3145 1.1 nonaka /* Move SPS into PWM mode. */ 3146 1.1 nonaka urtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b); 3147 1.49 nat DELAY(5); 3148 1.1 nonaka 3149 1.1 nonaka reg = urtwn_read_1(sc, R92C_LDOV12D_CTRL); 3150 1.1 nonaka if (!(reg & R92C_LDOV12D_CTRL_LDV12_EN)) { 3151 1.1 nonaka urtwn_write_1(sc, R92C_LDOV12D_CTRL, 3152 1.1 nonaka reg | R92C_LDOV12D_CTRL_LDV12_EN); 3153 1.1 nonaka DELAY(100); 3154 1.1 nonaka urtwn_write_1(sc, R92C_SYS_ISO_CTRL, 3155 1.1 nonaka urtwn_read_1(sc, R92C_SYS_ISO_CTRL) & 3156 1.1 nonaka ~R92C_SYS_ISO_CTRL_MD2PP); 3157 1.1 nonaka } 3158 1.1 nonaka 3159 1.1 nonaka /* Auto enable WLAN. */ 3160 1.1 nonaka urtwn_write_2(sc, R92C_APS_FSMCO, 3161 1.1 nonaka urtwn_read_2(sc, R92C_APS_FSMCO) | R92C_APS_FSMCO_APFM_ONMAC); 3162 1.1 nonaka for (ntries = 0; ntries < 1000; ntries++) { 3163 1.1 nonaka if (!(urtwn_read_2(sc, R92C_APS_FSMCO) & 3164 1.1 nonaka R92C_APS_FSMCO_APFM_ONMAC)) 3165 1.1 nonaka break; 3166 1.49 nat DELAY(100); 3167 1.1 nonaka } 3168 1.1 nonaka if (ntries == 1000) { 3169 1.1 nonaka aprint_error_dev(sc->sc_dev, 3170 1.1 nonaka "timeout waiting for MAC auto ON\n"); 3171 1.42 skrll return ETIMEDOUT; 3172 1.1 nonaka } 3173 1.1 nonaka 3174 1.1 nonaka /* Enable radio, GPIO and LED functions. */ 3175 1.1 nonaka KASSERT((R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_PDN_EN | 3176 1.1 nonaka R92C_APS_FSMCO_PFM_ALDN) == 0x0812); 3177 1.1 nonaka urtwn_write_2(sc, R92C_APS_FSMCO, 3178 1.1 nonaka R92C_APS_FSMCO_AFSM_HSUS | 3179 1.1 nonaka R92C_APS_FSMCO_PDN_EN | 3180 1.1 nonaka R92C_APS_FSMCO_PFM_ALDN); 3181 1.1 nonaka 3182 1.1 nonaka /* Release RF digital isolation. */ 3183 1.1 nonaka urtwn_write_2(sc, R92C_SYS_ISO_CTRL, 3184 1.1 nonaka urtwn_read_2(sc, R92C_SYS_ISO_CTRL) & ~R92C_SYS_ISO_CTRL_DIOR); 3185 1.1 nonaka 3186 1.1 nonaka /* Initialize MAC. */ 3187 1.1 nonaka urtwn_write_1(sc, R92C_APSD_CTRL, 3188 1.1 nonaka urtwn_read_1(sc, R92C_APSD_CTRL) & ~R92C_APSD_CTRL_OFF); 3189 1.1 nonaka for (ntries = 0; ntries < 200; ntries++) { 3190 1.1 nonaka if (!(urtwn_read_1(sc, R92C_APSD_CTRL) & 3191 1.1 nonaka R92C_APSD_CTRL_OFF_STATUS)) 3192 1.1 nonaka break; 3193 1.1 nonaka DELAY(5); 3194 1.1 nonaka } 3195 1.1 nonaka if (ntries == 200) { 3196 1.1 nonaka aprint_error_dev(sc->sc_dev, 3197 1.1 nonaka "timeout waiting for MAC initialization\n"); 3198 1.42 skrll return ETIMEDOUT; 3199 1.1 nonaka } 3200 1.1 nonaka 3201 1.1 nonaka /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */ 3202 1.1 nonaka reg = urtwn_read_2(sc, R92C_CR); 3203 1.1 nonaka reg |= R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN | 3204 1.1 nonaka R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN | 3205 1.1 nonaka R92C_CR_SCHEDULE_EN | R92C_CR_MACTXEN | R92C_CR_MACRXEN | 3206 1.1 nonaka R92C_CR_ENSEC; 3207 1.1 nonaka urtwn_write_2(sc, R92C_CR, reg); 3208 1.1 nonaka 3209 1.1 nonaka urtwn_write_1(sc, 0xfe10, 0x19); 3210 1.100 nat 3211 1.100 nat urtwn_delay_ms(sc, 1); 3212 1.100 nat 3213 1.42 skrll return 0; 3214 1.1 nonaka } 3215 1.1 nonaka 3216 1.1 nonaka static int 3217 1.49 nat urtwn_r92e_power_on(struct urtwn_softc *sc) 3218 1.49 nat { 3219 1.49 nat uint32_t reg; 3220 1.49 nat uint32_t val; 3221 1.49 nat int ntries; 3222 1.49 nat 3223 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 3224 1.49 nat 3225 1.49 nat KASSERT(mutex_owned(&sc->sc_write_mtx)); 3226 1.49 nat 3227 1.49 nat /* Enable radio, GPIO and LED functions. */ 3228 1.49 nat KASSERT((R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_PDN_EN | 3229 1.49 nat R92C_APS_FSMCO_PFM_ALDN) == 0x0812); 3230 1.49 nat urtwn_write_2(sc, R92C_APS_FSMCO, 3231 1.49 nat R92C_APS_FSMCO_AFSM_HSUS | 3232 1.49 nat R92C_APS_FSMCO_PDN_EN | 3233 1.49 nat R92C_APS_FSMCO_PFM_ALDN); 3234 1.49 nat 3235 1.49 nat if (urtwn_read_4(sc, R92E_SYS_CFG1_8192E) & R92E_SPSLDO_SEL){ 3236 1.49 nat /* LDO. */ 3237 1.52 skrll urtwn_write_1(sc, R92E_LDO_SWR_CTRL, 0xc3); 3238 1.49 nat } 3239 1.49 nat else { 3240 1.49 nat urtwn_write_2(sc, R92C_SYS_SWR_CTRL2, urtwn_read_2(sc, 3241 1.49 nat R92C_SYS_SWR_CTRL2) & 0xffff); 3242 1.49 nat urtwn_write_1(sc, R92E_LDO_SWR_CTRL, 0x83); 3243 1.49 nat } 3244 1.49 nat 3245 1.49 nat for (ntries = 0; ntries < 2; ntries++) { 3246 1.49 nat urtwn_write_1(sc, R92C_AFE_PLL_CTRL, 3247 1.49 nat urtwn_read_1(sc, R92C_AFE_PLL_CTRL)); 3248 1.49 nat urtwn_write_2(sc, R92C_AFE_CTRL4, urtwn_read_2(sc, 3249 1.49 nat R92C_AFE_CTRL4)); 3250 1.49 nat } 3251 1.49 nat 3252 1.49 nat /* Reset BB. */ 3253 1.49 nat urtwn_write_1(sc, R92C_SYS_FUNC_EN, 3254 1.49 nat urtwn_read_1(sc, R92C_SYS_FUNC_EN) & ~(R92C_SYS_FUNC_EN_BBRSTB | 3255 1.49 nat R92C_SYS_FUNC_EN_BB_GLB_RST)); 3256 1.49 nat 3257 1.49 nat urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 2, urtwn_read_1(sc, 3258 1.49 nat R92C_AFE_XTAL_CTRL + 2) | 0x80); 3259 1.49 nat 3260 1.49 nat /* Disable HWPDN. */ 3261 1.49 nat urtwn_write_2(sc, R92C_APS_FSMCO, urtwn_read_2(sc, 3262 1.49 nat R92C_APS_FSMCO) & ~R92C_APS_FSMCO_APDM_HPDN); 3263 1.49 nat 3264 1.49 nat /* Disable WL suspend. */ 3265 1.49 nat urtwn_write_2(sc, R92C_APS_FSMCO, urtwn_read_2(sc, 3266 1.49 nat R92C_APS_FSMCO) & ~(R92C_APS_FSMCO_AFSM_PCIE | 3267 1.49 nat R92C_APS_FSMCO_AFSM_HSUS)); 3268 1.49 nat 3269 1.49 nat urtwn_write_4(sc, R92C_APS_FSMCO, urtwn_read_4(sc, 3270 1.49 nat R92C_APS_FSMCO) | R92C_APS_FSMCO_RDY_MACON); 3271 1.49 nat urtwn_write_2(sc, R92C_APS_FSMCO, urtwn_read_2(sc, 3272 1.49 nat R92C_APS_FSMCO) | R92C_APS_FSMCO_APFM_ONMAC); 3273 1.49 nat for (ntries = 0; ntries < 10000; ntries++) { 3274 1.49 nat val = urtwn_read_2(sc, R92C_APS_FSMCO) & 3275 1.49 nat R92C_APS_FSMCO_APFM_ONMAC; 3276 1.49 nat if (val == 0x0) 3277 1.49 nat break; 3278 1.49 nat DELAY(10); 3279 1.49 nat } 3280 1.49 nat if (ntries == 10000) { 3281 1.49 nat aprint_error_dev(sc->sc_dev, 3282 1.49 nat "timeout waiting for chip power up\n"); 3283 1.49 nat return ETIMEDOUT; 3284 1.49 nat } 3285 1.52 skrll 3286 1.49 nat urtwn_write_2(sc, R92C_CR, 0x00); 3287 1.49 nat reg = urtwn_read_2(sc, R92C_CR); 3288 1.49 nat reg |= R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN | 3289 1.49 nat R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN | 3290 1.49 nat R92C_CR_SCHEDULE_EN | R92C_CR_ENSEC; 3291 1.49 nat urtwn_write_2(sc, R92C_CR, reg); 3292 1.49 nat 3293 1.49 nat return 0; 3294 1.49 nat } 3295 1.49 nat 3296 1.49 nat static int 3297 1.32 nonaka urtwn_r88e_power_on(struct urtwn_softc *sc) 3298 1.32 nonaka { 3299 1.32 nonaka uint32_t reg; 3300 1.32 nonaka uint8_t val; 3301 1.32 nonaka int ntries; 3302 1.32 nonaka 3303 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 3304 1.32 nonaka 3305 1.32 nonaka KASSERT(mutex_owned(&sc->sc_write_mtx)); 3306 1.32 nonaka 3307 1.32 nonaka /* Wait for power ready bit. */ 3308 1.32 nonaka for (ntries = 0; ntries < 5000; ntries++) { 3309 1.32 nonaka val = urtwn_read_1(sc, 0x6) & 0x2; 3310 1.32 nonaka if (val == 0x2) 3311 1.32 nonaka break; 3312 1.32 nonaka DELAY(10); 3313 1.32 nonaka } 3314 1.32 nonaka if (ntries == 5000) { 3315 1.32 nonaka aprint_error_dev(sc->sc_dev, 3316 1.32 nonaka "timeout waiting for chip power up\n"); 3317 1.42 skrll return ETIMEDOUT; 3318 1.32 nonaka } 3319 1.32 nonaka 3320 1.32 nonaka /* Reset BB. */ 3321 1.32 nonaka urtwn_write_1(sc, R92C_SYS_FUNC_EN, 3322 1.32 nonaka urtwn_read_1(sc, R92C_SYS_FUNC_EN) & ~(R92C_SYS_FUNC_EN_BBRSTB | 3323 1.32 nonaka R92C_SYS_FUNC_EN_BB_GLB_RST)); 3324 1.32 nonaka 3325 1.32 nonaka urtwn_write_1(sc, 0x26, urtwn_read_1(sc, 0x26) | 0x80); 3326 1.32 nonaka 3327 1.32 nonaka /* Disable HWPDN. */ 3328 1.32 nonaka urtwn_write_1(sc, 0x5, urtwn_read_1(sc, 0x5) & ~0x80); 3329 1.32 nonaka 3330 1.32 nonaka /* Disable WL suspend. */ 3331 1.32 nonaka urtwn_write_1(sc, 0x5, urtwn_read_1(sc, 0x5) & ~0x18); 3332 1.32 nonaka 3333 1.32 nonaka urtwn_write_1(sc, 0x5, urtwn_read_1(sc, 0x5) | 0x1); 3334 1.32 nonaka for (ntries = 0; ntries < 5000; ntries++) { 3335 1.32 nonaka if (!(urtwn_read_1(sc, 0x5) & 0x1)) 3336 1.32 nonaka break; 3337 1.32 nonaka DELAY(10); 3338 1.32 nonaka } 3339 1.32 nonaka if (ntries == 5000) 3340 1.42 skrll return ETIMEDOUT; 3341 1.32 nonaka 3342 1.32 nonaka /* Enable LDO normal mode. */ 3343 1.32 nonaka urtwn_write_1(sc, 0x23, urtwn_read_1(sc, 0x23) & ~0x10); 3344 1.32 nonaka 3345 1.32 nonaka /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */ 3346 1.32 nonaka urtwn_write_2(sc, R92C_CR, 0); 3347 1.32 nonaka reg = urtwn_read_2(sc, R92C_CR); 3348 1.32 nonaka reg |= R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN | 3349 1.32 nonaka R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN | 3350 1.32 nonaka R92C_CR_SCHEDULE_EN | R92C_CR_ENSEC | R92C_CR_CALTMR_EN; 3351 1.32 nonaka urtwn_write_2(sc, R92C_CR, reg); 3352 1.32 nonaka 3353 1.42 skrll return 0; 3354 1.32 nonaka } 3355 1.32 nonaka 3356 1.88 jdolecek static int __noinline 3357 1.1 nonaka urtwn_llt_init(struct urtwn_softc *sc) 3358 1.1 nonaka { 3359 1.32 nonaka size_t i, page_count, pktbuf_count; 3360 1.49 nat uint32_t val; 3361 1.22 christos int error; 3362 1.1 nonaka 3363 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 3364 1.1 nonaka 3365 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 3366 1.12 christos 3367 1.52 skrll if (sc->chip & URTWN_CHIP_88E) 3368 1.49 nat page_count = R88E_TX_PAGE_COUNT; 3369 1.52 skrll else if (sc->chip & URTWN_CHIP_92EU) 3370 1.49 nat page_count = R92E_TX_PAGE_COUNT; 3371 1.49 nat else 3372 1.49 nat page_count = R92C_TX_PAGE_COUNT; 3373 1.49 nat if (sc->chip & URTWN_CHIP_88E) 3374 1.49 nat pktbuf_count = R88E_TXPKTBUF_COUNT; 3375 1.49 nat else if (sc->chip & URTWN_CHIP_92EU) 3376 1.117 nat pktbuf_count = R92E_TXPKTBUF_COUNT; 3377 1.49 nat else 3378 1.49 nat pktbuf_count = R92C_TXPKTBUF_COUNT; 3379 1.49 nat 3380 1.49 nat if (sc->chip & URTWN_CHIP_92EU) { 3381 1.49 nat val = urtwn_read_4(sc, R92E_AUTO_LLT) | R92E_AUTO_LLT_EN; 3382 1.49 nat urtwn_write_4(sc, R92E_AUTO_LLT, val); 3383 1.49 nat DELAY(100); 3384 1.49 nat val = urtwn_read_4(sc, R92E_AUTO_LLT); 3385 1.49 nat if (val & R92E_AUTO_LLT_EN) 3386 1.49 nat return EIO; 3387 1.49 nat return 0; 3388 1.49 nat } 3389 1.32 nonaka 3390 1.32 nonaka /* Reserve pages [0; page_count]. */ 3391 1.32 nonaka for (i = 0; i < page_count; i++) { 3392 1.1 nonaka if ((error = urtwn_llt_write(sc, i, i + 1)) != 0) 3393 1.42 skrll return error; 3394 1.1 nonaka } 3395 1.1 nonaka /* NB: 0xff indicates end-of-list. */ 3396 1.1 nonaka if ((error = urtwn_llt_write(sc, i, 0xff)) != 0) 3397 1.42 skrll return error; 3398 1.1 nonaka /* 3399 1.32 nonaka * Use pages [page_count + 1; pktbuf_count - 1] 3400 1.1 nonaka * as ring buffer. 3401 1.1 nonaka */ 3402 1.32 nonaka for (++i; i < pktbuf_count - 1; i++) { 3403 1.1 nonaka if ((error = urtwn_llt_write(sc, i, i + 1)) != 0) 3404 1.42 skrll return error; 3405 1.1 nonaka } 3406 1.1 nonaka /* Make the last page point to the beginning of the ring buffer. */ 3407 1.32 nonaka error = urtwn_llt_write(sc, i, pktbuf_count + 1); 3408 1.42 skrll return error; 3409 1.1 nonaka } 3410 1.1 nonaka 3411 1.1 nonaka static void 3412 1.1 nonaka urtwn_fw_reset(struct urtwn_softc *sc) 3413 1.1 nonaka { 3414 1.1 nonaka uint16_t reg; 3415 1.1 nonaka int ntries; 3416 1.1 nonaka 3417 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 3418 1.1 nonaka 3419 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 3420 1.12 christos 3421 1.1 nonaka /* Tell 8051 to reset itself. */ 3422 1.99 nat mutex_enter(&sc->sc_fwcmd_mtx); 3423 1.1 nonaka urtwn_write_1(sc, R92C_HMETFR + 3, 0x20); 3424 1.99 nat sc->fwcur = 0; 3425 1.99 nat mutex_exit(&sc->sc_fwcmd_mtx); 3426 1.1 nonaka 3427 1.1 nonaka /* Wait until 8051 resets by itself. */ 3428 1.1 nonaka for (ntries = 0; ntries < 100; ntries++) { 3429 1.1 nonaka reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN); 3430 1.1 nonaka if (!(reg & R92C_SYS_FUNC_EN_CPUEN)) 3431 1.1 nonaka return; 3432 1.1 nonaka DELAY(50); 3433 1.1 nonaka } 3434 1.1 nonaka /* Force 8051 reset. */ 3435 1.32 nonaka urtwn_write_2(sc, R92C_SYS_FUNC_EN, 3436 1.32 nonaka urtwn_read_2(sc, R92C_SYS_FUNC_EN) & ~R92C_SYS_FUNC_EN_CPUEN); 3437 1.32 nonaka } 3438 1.32 nonaka 3439 1.32 nonaka static void 3440 1.32 nonaka urtwn_r88e_fw_reset(struct urtwn_softc *sc) 3441 1.32 nonaka { 3442 1.32 nonaka uint16_t reg; 3443 1.32 nonaka 3444 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 3445 1.32 nonaka 3446 1.32 nonaka KASSERT(mutex_owned(&sc->sc_write_mtx)); 3447 1.32 nonaka 3448 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_92EU)) { 3449 1.49 nat reg = urtwn_read_2(sc, R92C_RSV_CTRL) & ~R92E_RSV_MIO_EN; 3450 1.49 nat urtwn_write_2(sc,R92C_RSV_CTRL, reg); 3451 1.49 nat } 3452 1.49 nat DELAY(50); 3453 1.49 nat 3454 1.32 nonaka reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN); 3455 1.1 nonaka urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN); 3456 1.49 nat DELAY(50); 3457 1.49 nat 3458 1.32 nonaka urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg | R92C_SYS_FUNC_EN_CPUEN); 3459 1.49 nat DELAY(50); 3460 1.49 nat 3461 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_92EU)) { 3462 1.49 nat reg = urtwn_read_2(sc, R92C_RSV_CTRL) | R92E_RSV_MIO_EN; 3463 1.49 nat urtwn_write_2(sc,R92C_RSV_CTRL, reg); 3464 1.49 nat } 3465 1.49 nat DELAY(50); 3466 1.49 nat 3467 1.99 nat mutex_enter(&sc->sc_fwcmd_mtx); 3468 1.99 nat /* Init firmware commands ring. */ 3469 1.99 nat sc->fwcur = 0; 3470 1.99 nat mutex_exit(&sc->sc_fwcmd_mtx); 3471 1.99 nat 3472 1.1 nonaka } 3473 1.1 nonaka 3474 1.1 nonaka static int 3475 1.1 nonaka urtwn_fw_loadpage(struct urtwn_softc *sc, int page, uint8_t *buf, int len) 3476 1.1 nonaka { 3477 1.1 nonaka uint32_t reg; 3478 1.1 nonaka int off, mlen, error = 0; 3479 1.1 nonaka 3480 1.74 gson URTWNHIST_FUNC(); 3481 1.74 gson URTWNHIST_CALLARGS("page=%jd, buf=%#jx, len=%jd", 3482 1.74 gson page, (uintptr_t)buf, len, 0); 3483 1.1 nonaka 3484 1.1 nonaka reg = urtwn_read_4(sc, R92C_MCUFWDL); 3485 1.1 nonaka reg = RW(reg, R92C_MCUFWDL_PAGE, page); 3486 1.1 nonaka urtwn_write_4(sc, R92C_MCUFWDL, reg); 3487 1.1 nonaka 3488 1.1 nonaka off = R92C_FW_START_ADDR; 3489 1.1 nonaka while (len > 0) { 3490 1.1 nonaka if (len > 196) 3491 1.1 nonaka mlen = 196; 3492 1.1 nonaka else if (len > 4) 3493 1.1 nonaka mlen = 4; 3494 1.1 nonaka else 3495 1.1 nonaka mlen = 1; 3496 1.1 nonaka error = urtwn_write_region(sc, off, buf, mlen); 3497 1.1 nonaka if (error != 0) 3498 1.1 nonaka break; 3499 1.1 nonaka off += mlen; 3500 1.1 nonaka buf += mlen; 3501 1.1 nonaka len -= mlen; 3502 1.1 nonaka } 3503 1.42 skrll return error; 3504 1.1 nonaka } 3505 1.1 nonaka 3506 1.88 jdolecek static int __noinline 3507 1.1 nonaka urtwn_load_firmware(struct urtwn_softc *sc) 3508 1.1 nonaka { 3509 1.1 nonaka firmware_handle_t fwh; 3510 1.1 nonaka const struct r92c_fw_hdr *hdr; 3511 1.1 nonaka const char *name; 3512 1.1 nonaka u_char *fw, *ptr; 3513 1.1 nonaka size_t len; 3514 1.1 nonaka uint32_t reg; 3515 1.1 nonaka int mlen, ntries, page, error; 3516 1.1 nonaka 3517 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 3518 1.1 nonaka 3519 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 3520 1.12 christos 3521 1.1 nonaka /* Read firmware image from the filesystem. */ 3522 1.32 nonaka if (ISSET(sc->chip, URTWN_CHIP_88E)) 3523 1.32 nonaka name = "rtl8188eufw.bin"; 3524 1.49 nat else if (ISSET(sc->chip, URTWN_CHIP_92EU)) 3525 1.49 nat name = "rtl8192eefw.bin"; 3526 1.32 nonaka else if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) == 3527 1.1 nonaka URTWN_CHIP_UMC_A_CUT) 3528 1.5 riz name = "rtl8192cfwU.bin"; 3529 1.1 nonaka else 3530 1.5 riz name = "rtl8192cfw.bin"; 3531 1.5 riz if ((error = firmware_open("if_urtwn", name, &fwh)) != 0) { 3532 1.1 nonaka aprint_error_dev(sc->sc_dev, 3533 1.32 nonaka "failed load firmware of file %s (error %d)\n", name, 3534 1.32 nonaka error); 3535 1.42 skrll return error; 3536 1.1 nonaka } 3537 1.36 jmcneill const size_t fwlen = len = firmware_get_size(fwh); 3538 1.1 nonaka fw = firmware_malloc(len); 3539 1.1 nonaka if (fw == NULL) { 3540 1.1 nonaka aprint_error_dev(sc->sc_dev, 3541 1.1 nonaka "failed to allocate firmware memory\n"); 3542 1.1 nonaka firmware_close(fwh); 3543 1.42 skrll return ENOMEM; 3544 1.1 nonaka } 3545 1.1 nonaka error = firmware_read(fwh, 0, fw, len); 3546 1.1 nonaka firmware_close(fwh); 3547 1.1 nonaka if (error != 0) { 3548 1.1 nonaka aprint_error_dev(sc->sc_dev, 3549 1.1 nonaka "failed to read firmware (error %d)\n", error); 3550 1.36 jmcneill firmware_free(fw, fwlen); 3551 1.42 skrll return error; 3552 1.1 nonaka } 3553 1.1 nonaka 3554 1.49 nat len = fwlen; 3555 1.1 nonaka ptr = fw; 3556 1.1 nonaka hdr = (const struct r92c_fw_hdr *)ptr; 3557 1.1 nonaka /* Check if there is a valid FW header and skip it. */ 3558 1.1 nonaka if ((le16toh(hdr->signature) >> 4) == 0x88c || 3559 1.32 nonaka (le16toh(hdr->signature) >> 4) == 0x88e || 3560 1.49 nat (le16toh(hdr->signature) >> 4) == 0x92e || 3561 1.1 nonaka (le16toh(hdr->signature) >> 4) == 0x92c) { 3562 1.74 gson DPRINTFN(DBG_INIT, "FW V%jd.%jd", 3563 1.74 gson le16toh(hdr->version), le16toh(hdr->subversion), 0, 0); 3564 1.74 gson DPRINTFN(DBG_INIT, "%02jd-%02jd %02jd:%02jd", 3565 1.74 gson hdr->month, hdr->date, hdr->hour, hdr->minute); 3566 1.1 nonaka ptr += sizeof(*hdr); 3567 1.1 nonaka len -= sizeof(*hdr); 3568 1.1 nonaka } 3569 1.1 nonaka 3570 1.32 nonaka if (urtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RAM_DL_SEL) { 3571 1.76 mlelstv /* Reset MCU ready status */ 3572 1.76 mlelstv urtwn_write_1(sc, R92C_MCUFWDL, 0); 3573 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_88E) || 3574 1.49 nat ISSET(sc->chip, URTWN_CHIP_92EU)) 3575 1.32 nonaka urtwn_r88e_fw_reset(sc); 3576 1.32 nonaka else 3577 1.32 nonaka urtwn_fw_reset(sc); 3578 1.1 nonaka } 3579 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_88E) && 3580 1.49 nat !ISSET(sc->chip, URTWN_CHIP_92EU)) { 3581 1.32 nonaka urtwn_write_2(sc, R92C_SYS_FUNC_EN, 3582 1.32 nonaka urtwn_read_2(sc, R92C_SYS_FUNC_EN) | 3583 1.32 nonaka R92C_SYS_FUNC_EN_CPUEN); 3584 1.32 nonaka } 3585 1.1 nonaka 3586 1.1 nonaka /* download enabled */ 3587 1.1 nonaka urtwn_write_1(sc, R92C_MCUFWDL, 3588 1.1 nonaka urtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_EN); 3589 1.1 nonaka urtwn_write_1(sc, R92C_MCUFWDL + 2, 3590 1.1 nonaka urtwn_read_1(sc, R92C_MCUFWDL + 2) & ~0x08); 3591 1.1 nonaka 3592 1.32 nonaka /* Reset the FWDL checksum. */ 3593 1.32 nonaka urtwn_write_1(sc, R92C_MCUFWDL, 3594 1.52 skrll urtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_CHKSUM_RPT); 3595 1.32 nonaka 3596 1.49 nat DELAY(50); 3597 1.1 nonaka /* download firmware */ 3598 1.1 nonaka for (page = 0; len > 0; page++) { 3599 1.1 nonaka mlen = MIN(len, R92C_FW_PAGE_SIZE); 3600 1.1 nonaka error = urtwn_fw_loadpage(sc, page, ptr, mlen); 3601 1.1 nonaka if (error != 0) { 3602 1.1 nonaka aprint_error_dev(sc->sc_dev, 3603 1.1 nonaka "could not load firmware page %d\n", page); 3604 1.1 nonaka goto fail; 3605 1.1 nonaka } 3606 1.1 nonaka ptr += mlen; 3607 1.1 nonaka len -= mlen; 3608 1.1 nonaka } 3609 1.1 nonaka 3610 1.1 nonaka /* download disable */ 3611 1.1 nonaka urtwn_write_1(sc, R92C_MCUFWDL, 3612 1.1 nonaka urtwn_read_1(sc, R92C_MCUFWDL) & ~R92C_MCUFWDL_EN); 3613 1.1 nonaka urtwn_write_1(sc, R92C_MCUFWDL + 1, 0); 3614 1.1 nonaka 3615 1.1 nonaka /* Wait for checksum report. */ 3616 1.1 nonaka for (ntries = 0; ntries < 1000; ntries++) { 3617 1.1 nonaka if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_CHKSUM_RPT) 3618 1.1 nonaka break; 3619 1.1 nonaka DELAY(5); 3620 1.1 nonaka } 3621 1.1 nonaka if (ntries == 1000) { 3622 1.1 nonaka aprint_error_dev(sc->sc_dev, 3623 1.1 nonaka "timeout waiting for checksum report\n"); 3624 1.1 nonaka error = ETIMEDOUT; 3625 1.1 nonaka goto fail; 3626 1.1 nonaka } 3627 1.1 nonaka 3628 1.1 nonaka /* Wait for firmware readiness. */ 3629 1.1 nonaka reg = urtwn_read_4(sc, R92C_MCUFWDL); 3630 1.1 nonaka reg = (reg & ~R92C_MCUFWDL_WINTINI_RDY) | R92C_MCUFWDL_RDY; 3631 1.1 nonaka urtwn_write_4(sc, R92C_MCUFWDL, reg); 3632 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_88E) || 3633 1.49 nat ISSET(sc->chip, URTWN_CHIP_92EU)) 3634 1.32 nonaka urtwn_r88e_fw_reset(sc); 3635 1.66 msaitoh for (ntries = 0; ntries < 6000; ntries++) { 3636 1.1 nonaka if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_WINTINI_RDY) 3637 1.1 nonaka break; 3638 1.1 nonaka DELAY(5); 3639 1.1 nonaka } 3640 1.66 msaitoh if (ntries == 6000) { 3641 1.1 nonaka aprint_error_dev(sc->sc_dev, 3642 1.1 nonaka "timeout waiting for firmware readiness\n"); 3643 1.1 nonaka error = ETIMEDOUT; 3644 1.1 nonaka goto fail; 3645 1.1 nonaka } 3646 1.1 nonaka fail: 3647 1.36 jmcneill firmware_free(fw, fwlen); 3648 1.42 skrll return error; 3649 1.1 nonaka } 3650 1.1 nonaka 3651 1.32 nonaka static __inline int 3652 1.32 nonaka urtwn_dma_init(struct urtwn_softc *sc) 3653 1.32 nonaka { 3654 1.32 nonaka 3655 1.32 nonaka return sc->sc_dma_init(sc); 3656 1.32 nonaka } 3657 1.32 nonaka 3658 1.1 nonaka static int 3659 1.32 nonaka urtwn_r92c_dma_init(struct urtwn_softc *sc) 3660 1.1 nonaka { 3661 1.1 nonaka int hashq, hasnq, haslq, nqueues, nqpages, nrempages; 3662 1.1 nonaka uint32_t reg; 3663 1.1 nonaka int error; 3664 1.1 nonaka 3665 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 3666 1.1 nonaka 3667 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 3668 1.12 christos 3669 1.1 nonaka /* Initialize LLT table. */ 3670 1.1 nonaka error = urtwn_llt_init(sc); 3671 1.1 nonaka if (error != 0) 3672 1.42 skrll return error; 3673 1.1 nonaka 3674 1.1 nonaka /* Get Tx queues to USB endpoints mapping. */ 3675 1.1 nonaka hashq = hasnq = haslq = 0; 3676 1.1 nonaka reg = urtwn_read_2(sc, R92C_USB_EP + 1); 3677 1.75 gson DPRINTFN(DBG_INIT, "USB endpoints mapping %#jx", reg, 0, 0, 0); 3678 1.1 nonaka if (MS(reg, R92C_USB_EP_HQ) != 0) 3679 1.1 nonaka hashq = 1; 3680 1.1 nonaka if (MS(reg, R92C_USB_EP_NQ) != 0) 3681 1.1 nonaka hasnq = 1; 3682 1.1 nonaka if (MS(reg, R92C_USB_EP_LQ) != 0) 3683 1.1 nonaka haslq = 1; 3684 1.1 nonaka nqueues = hashq + hasnq + haslq; 3685 1.1 nonaka if (nqueues == 0) 3686 1.42 skrll return EIO; 3687 1.1 nonaka /* Get the number of pages for each queue. */ 3688 1.1 nonaka nqpages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) / nqueues; 3689 1.1 nonaka /* The remaining pages are assigned to the high priority queue. */ 3690 1.1 nonaka nrempages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) % nqueues; 3691 1.1 nonaka 3692 1.1 nonaka /* Set number of pages for normal priority queue. */ 3693 1.1 nonaka urtwn_write_1(sc, R92C_RQPN_NPQ, hasnq ? nqpages : 0); 3694 1.1 nonaka urtwn_write_4(sc, R92C_RQPN, 3695 1.1 nonaka /* Set number of pages for public queue. */ 3696 1.1 nonaka SM(R92C_RQPN_PUBQ, R92C_PUBQ_NPAGES) | 3697 1.1 nonaka /* Set number of pages for high priority queue. */ 3698 1.1 nonaka SM(R92C_RQPN_HPQ, hashq ? nqpages + nrempages : 0) | 3699 1.1 nonaka /* Set number of pages for low priority queue. */ 3700 1.1 nonaka SM(R92C_RQPN_LPQ, haslq ? nqpages : 0) | 3701 1.1 nonaka /* Load values. */ 3702 1.1 nonaka R92C_RQPN_LD); 3703 1.1 nonaka 3704 1.1 nonaka urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R92C_TX_PAGE_BOUNDARY); 3705 1.1 nonaka urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R92C_TX_PAGE_BOUNDARY); 3706 1.1 nonaka urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, R92C_TX_PAGE_BOUNDARY); 3707 1.1 nonaka urtwn_write_1(sc, R92C_TRXFF_BNDY, R92C_TX_PAGE_BOUNDARY); 3708 1.1 nonaka urtwn_write_1(sc, R92C_TDECTRL + 1, R92C_TX_PAGE_BOUNDARY); 3709 1.1 nonaka 3710 1.1 nonaka /* Set queue to USB pipe mapping. */ 3711 1.1 nonaka reg = urtwn_read_2(sc, R92C_TRXDMA_CTRL); 3712 1.1 nonaka reg &= ~R92C_TRXDMA_CTRL_QMAP_M; 3713 1.1 nonaka if (nqueues == 1) { 3714 1.1 nonaka if (hashq) { 3715 1.1 nonaka reg |= R92C_TRXDMA_CTRL_QMAP_HQ; 3716 1.1 nonaka } else if (hasnq) { 3717 1.1 nonaka reg |= R92C_TRXDMA_CTRL_QMAP_NQ; 3718 1.1 nonaka } else { 3719 1.1 nonaka reg |= R92C_TRXDMA_CTRL_QMAP_LQ; 3720 1.1 nonaka } 3721 1.1 nonaka } else if (nqueues == 2) { 3722 1.1 nonaka /* All 2-endpoints configs have a high priority queue. */ 3723 1.1 nonaka if (!hashq) { 3724 1.42 skrll return EIO; 3725 1.1 nonaka } 3726 1.1 nonaka if (hasnq) { 3727 1.1 nonaka reg |= R92C_TRXDMA_CTRL_QMAP_HQ_NQ; 3728 1.1 nonaka } else { 3729 1.1 nonaka reg |= R92C_TRXDMA_CTRL_QMAP_HQ_LQ; 3730 1.1 nonaka } 3731 1.1 nonaka } else { 3732 1.1 nonaka reg |= R92C_TRXDMA_CTRL_QMAP_3EP; 3733 1.1 nonaka } 3734 1.1 nonaka urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg); 3735 1.1 nonaka 3736 1.1 nonaka /* Set Tx/Rx transfer page boundary. */ 3737 1.1 nonaka urtwn_write_2(sc, R92C_TRXFF_BNDY + 2, 0x27ff); 3738 1.1 nonaka 3739 1.1 nonaka /* Set Tx/Rx transfer page size. */ 3740 1.1 nonaka urtwn_write_1(sc, R92C_PBP, 3741 1.1 nonaka SM(R92C_PBP_PSRX, R92C_PBP_128) | SM(R92C_PBP_PSTX, R92C_PBP_128)); 3742 1.42 skrll return 0; 3743 1.1 nonaka } 3744 1.1 nonaka 3745 1.32 nonaka static int 3746 1.32 nonaka urtwn_r88e_dma_init(struct urtwn_softc *sc) 3747 1.32 nonaka { 3748 1.32 nonaka usb_interface_descriptor_t *id; 3749 1.32 nonaka uint32_t reg; 3750 1.32 nonaka int nqueues; 3751 1.32 nonaka int error; 3752 1.32 nonaka 3753 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 3754 1.32 nonaka 3755 1.32 nonaka KASSERT(mutex_owned(&sc->sc_write_mtx)); 3756 1.32 nonaka 3757 1.32 nonaka /* Initialize LLT table. */ 3758 1.32 nonaka error = urtwn_llt_init(sc); 3759 1.32 nonaka if (error != 0) 3760 1.42 skrll return error; 3761 1.32 nonaka 3762 1.32 nonaka /* Get Tx queues to USB endpoints mapping. */ 3763 1.32 nonaka id = usbd_get_interface_descriptor(sc->sc_iface); 3764 1.32 nonaka nqueues = id->bNumEndpoints - 1; 3765 1.32 nonaka if (nqueues == 0) 3766 1.42 skrll return EIO; 3767 1.32 nonaka 3768 1.32 nonaka /* Set number of pages for normal priority queue. */ 3769 1.32 nonaka urtwn_write_2(sc, R92C_RQPN_NPQ, 0); 3770 1.32 nonaka urtwn_write_2(sc, R92C_RQPN_NPQ, 0x000d); 3771 1.32 nonaka urtwn_write_4(sc, R92C_RQPN, 0x808e000d); 3772 1.32 nonaka 3773 1.32 nonaka urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R88E_TX_PAGE_BOUNDARY); 3774 1.32 nonaka urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R88E_TX_PAGE_BOUNDARY); 3775 1.32 nonaka urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, R88E_TX_PAGE_BOUNDARY); 3776 1.32 nonaka urtwn_write_1(sc, R92C_TRXFF_BNDY, R88E_TX_PAGE_BOUNDARY); 3777 1.32 nonaka urtwn_write_1(sc, R92C_TDECTRL + 1, R88E_TX_PAGE_BOUNDARY); 3778 1.32 nonaka 3779 1.32 nonaka /* Set queue to USB pipe mapping. */ 3780 1.32 nonaka reg = urtwn_read_2(sc, R92C_TRXDMA_CTRL); 3781 1.32 nonaka reg &= ~R92C_TRXDMA_CTRL_QMAP_M; 3782 1.32 nonaka if (nqueues == 1) 3783 1.32 nonaka reg |= R92C_TRXDMA_CTRL_QMAP_LQ; 3784 1.32 nonaka else if (nqueues == 2) 3785 1.32 nonaka reg |= R92C_TRXDMA_CTRL_QMAP_HQ_NQ; 3786 1.32 nonaka else 3787 1.32 nonaka reg |= R92C_TRXDMA_CTRL_QMAP_3EP; 3788 1.32 nonaka urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg); 3789 1.32 nonaka 3790 1.32 nonaka /* Set Tx/Rx transfer page boundary. */ 3791 1.32 nonaka urtwn_write_2(sc, R92C_TRXFF_BNDY + 2, 0x23ff); 3792 1.32 nonaka 3793 1.32 nonaka /* Set Tx/Rx transfer page size. */ 3794 1.32 nonaka urtwn_write_1(sc, R92C_PBP, 3795 1.32 nonaka SM(R92C_PBP_PSRX, R92C_PBP_128) | SM(R92C_PBP_PSTX, R92C_PBP_128)); 3796 1.32 nonaka 3797 1.42 skrll return 0; 3798 1.32 nonaka } 3799 1.32 nonaka 3800 1.88 jdolecek static void __noinline 3801 1.1 nonaka urtwn_mac_init(struct urtwn_softc *sc) 3802 1.1 nonaka { 3803 1.22 christos size_t i; 3804 1.1 nonaka 3805 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 3806 1.1 nonaka 3807 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 3808 1.12 christos 3809 1.1 nonaka /* Write MAC initialization values. */ 3810 1.32 nonaka if (ISSET(sc->chip, URTWN_CHIP_88E)) { 3811 1.32 nonaka for (i = 0; i < __arraycount(rtl8188eu_mac); i++) 3812 1.32 nonaka urtwn_write_1(sc, rtl8188eu_mac[i].reg, 3813 1.32 nonaka rtl8188eu_mac[i].val); 3814 1.52 skrll } else if (ISSET(sc->chip, URTWN_CHIP_92EU)) { 3815 1.49 nat for (i = 0; i < __arraycount(rtl8192eu_mac); i++) 3816 1.49 nat urtwn_write_1(sc, rtl8192eu_mac[i].reg, 3817 1.49 nat rtl8192eu_mac[i].val); 3818 1.32 nonaka } else { 3819 1.32 nonaka for (i = 0; i < __arraycount(rtl8192cu_mac); i++) 3820 1.32 nonaka urtwn_write_1(sc, rtl8192cu_mac[i].reg, 3821 1.32 nonaka rtl8192cu_mac[i].val); 3822 1.32 nonaka } 3823 1.1 nonaka } 3824 1.1 nonaka 3825 1.88 jdolecek static void __noinline 3826 1.1 nonaka urtwn_bb_init(struct urtwn_softc *sc) 3827 1.1 nonaka { 3828 1.60 thorpej const struct rtwn_bb_prog *prog; 3829 1.1 nonaka uint32_t reg; 3830 1.32 nonaka uint8_t crystalcap; 3831 1.22 christos size_t i; 3832 1.1 nonaka 3833 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 3834 1.1 nonaka 3835 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 3836 1.12 christos 3837 1.1 nonaka /* Enable BB and RF. */ 3838 1.1 nonaka urtwn_write_2(sc, R92C_SYS_FUNC_EN, 3839 1.1 nonaka urtwn_read_2(sc, R92C_SYS_FUNC_EN) | 3840 1.1 nonaka R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST | 3841 1.1 nonaka R92C_SYS_FUNC_EN_DIO_RF); 3842 1.1 nonaka 3843 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_88E) && 3844 1.49 nat !ISSET(sc->chip, URTWN_CHIP_92EU)) { 3845 1.32 nonaka urtwn_write_1(sc, R92C_AFE_PLL_CTRL, 0x83); 3846 1.32 nonaka urtwn_write_1(sc, R92C_AFE_PLL_CTRL + 1, 0xdb); 3847 1.32 nonaka } 3848 1.1 nonaka 3849 1.1 nonaka urtwn_write_1(sc, R92C_RF_CTRL, 3850 1.1 nonaka R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB); 3851 1.1 nonaka urtwn_write_1(sc, R92C_SYS_FUNC_EN, 3852 1.1 nonaka R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD | 3853 1.1 nonaka R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_BBRSTB); 3854 1.1 nonaka 3855 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_88E) && 3856 1.49 nat !ISSET(sc->chip, URTWN_CHIP_92EU)) { 3857 1.32 nonaka urtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f); 3858 1.32 nonaka urtwn_write_1(sc, 0x15, 0xe9); 3859 1.32 nonaka urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80); 3860 1.32 nonaka } 3861 1.1 nonaka 3862 1.1 nonaka /* Select BB programming based on board type. */ 3863 1.32 nonaka if (ISSET(sc->chip, URTWN_CHIP_88E)) 3864 1.32 nonaka prog = &rtl8188eu_bb_prog; 3865 1.49 nat else if (ISSET(sc->chip, URTWN_CHIP_92EU)) 3866 1.49 nat prog = &rtl8192eu_bb_prog; 3867 1.32 nonaka else if (!(sc->chip & URTWN_CHIP_92C)) { 3868 1.1 nonaka if (sc->board_type == R92C_BOARD_TYPE_MINICARD) { 3869 1.1 nonaka prog = &rtl8188ce_bb_prog; 3870 1.1 nonaka } else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA) { 3871 1.1 nonaka prog = &rtl8188ru_bb_prog; 3872 1.1 nonaka } else { 3873 1.1 nonaka prog = &rtl8188cu_bb_prog; 3874 1.1 nonaka } 3875 1.1 nonaka } else { 3876 1.1 nonaka if (sc->board_type == R92C_BOARD_TYPE_MINICARD) { 3877 1.1 nonaka prog = &rtl8192ce_bb_prog; 3878 1.1 nonaka } else { 3879 1.1 nonaka prog = &rtl8192cu_bb_prog; 3880 1.1 nonaka } 3881 1.1 nonaka } 3882 1.1 nonaka /* Write BB initialization values. */ 3883 1.1 nonaka for (i = 0; i < prog->count; i++) { 3884 1.1 nonaka /* additional delay depend on registers */ 3885 1.1 nonaka switch (prog->regs[i]) { 3886 1.1 nonaka case 0xfe: 3887 1.49 nat urtwn_delay_ms(sc, 50); 3888 1.1 nonaka break; 3889 1.1 nonaka case 0xfd: 3890 1.49 nat urtwn_delay_ms(sc, 5); 3891 1.1 nonaka break; 3892 1.1 nonaka case 0xfc: 3893 1.49 nat urtwn_delay_ms(sc, 1); 3894 1.1 nonaka break; 3895 1.1 nonaka case 0xfb: 3896 1.1 nonaka DELAY(50); 3897 1.1 nonaka break; 3898 1.1 nonaka case 0xfa: 3899 1.1 nonaka DELAY(5); 3900 1.1 nonaka break; 3901 1.1 nonaka case 0xf9: 3902 1.1 nonaka DELAY(1); 3903 1.1 nonaka break; 3904 1.1 nonaka } 3905 1.1 nonaka urtwn_bb_write(sc, prog->regs[i], prog->vals[i]); 3906 1.1 nonaka DELAY(1); 3907 1.1 nonaka } 3908 1.1 nonaka 3909 1.1 nonaka if (sc->chip & URTWN_CHIP_92C_1T2R) { 3910 1.1 nonaka /* 8192C 1T only configuration. */ 3911 1.1 nonaka reg = urtwn_bb_read(sc, R92C_FPGA0_TXINFO); 3912 1.1 nonaka reg = (reg & ~0x00000003) | 0x2; 3913 1.1 nonaka urtwn_bb_write(sc, R92C_FPGA0_TXINFO, reg); 3914 1.1 nonaka 3915 1.1 nonaka reg = urtwn_bb_read(sc, R92C_FPGA1_TXINFO); 3916 1.1 nonaka reg = (reg & ~0x00300033) | 0x00200022; 3917 1.1 nonaka urtwn_bb_write(sc, R92C_FPGA1_TXINFO, reg); 3918 1.1 nonaka 3919 1.1 nonaka reg = urtwn_bb_read(sc, R92C_CCK0_AFESETTING); 3920 1.1 nonaka reg = (reg & ~0xff000000) | (0x45 << 24); 3921 1.1 nonaka urtwn_bb_write(sc, R92C_CCK0_AFESETTING, reg); 3922 1.1 nonaka 3923 1.1 nonaka reg = urtwn_bb_read(sc, R92C_OFDM0_TRXPATHENA); 3924 1.1 nonaka reg = (reg & ~0x000000ff) | 0x23; 3925 1.1 nonaka urtwn_bb_write(sc, R92C_OFDM0_TRXPATHENA, reg); 3926 1.1 nonaka 3927 1.1 nonaka reg = urtwn_bb_read(sc, R92C_OFDM0_AGCPARAM1); 3928 1.1 nonaka reg = (reg & ~0x00000030) | (1 << 4); 3929 1.1 nonaka urtwn_bb_write(sc, R92C_OFDM0_AGCPARAM1, reg); 3930 1.1 nonaka 3931 1.1 nonaka reg = urtwn_bb_read(sc, 0xe74); 3932 1.1 nonaka reg = (reg & ~0x0c000000) | (2 << 26); 3933 1.1 nonaka urtwn_bb_write(sc, 0xe74, reg); 3934 1.1 nonaka reg = urtwn_bb_read(sc, 0xe78); 3935 1.1 nonaka reg = (reg & ~0x0c000000) | (2 << 26); 3936 1.1 nonaka urtwn_bb_write(sc, 0xe78, reg); 3937 1.1 nonaka reg = urtwn_bb_read(sc, 0xe7c); 3938 1.1 nonaka reg = (reg & ~0x0c000000) | (2 << 26); 3939 1.1 nonaka urtwn_bb_write(sc, 0xe7c, reg); 3940 1.1 nonaka reg = urtwn_bb_read(sc, 0xe80); 3941 1.1 nonaka reg = (reg & ~0x0c000000) | (2 << 26); 3942 1.1 nonaka urtwn_bb_write(sc, 0xe80, reg); 3943 1.1 nonaka reg = urtwn_bb_read(sc, 0xe88); 3944 1.1 nonaka reg = (reg & ~0x0c000000) | (2 << 26); 3945 1.1 nonaka urtwn_bb_write(sc, 0xe88, reg); 3946 1.1 nonaka } 3947 1.1 nonaka 3948 1.1 nonaka /* Write AGC values. */ 3949 1.1 nonaka for (i = 0; i < prog->agccount; i++) { 3950 1.1 nonaka urtwn_bb_write(sc, R92C_OFDM0_AGCRSSITABLE, prog->agcvals[i]); 3951 1.1 nonaka DELAY(1); 3952 1.1 nonaka } 3953 1.1 nonaka 3954 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_88E) || 3955 1.49 nat ISSET(sc->chip, URTWN_CHIP_92EU)) { 3956 1.32 nonaka urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553422); 3957 1.32 nonaka DELAY(1); 3958 1.32 nonaka urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553420); 3959 1.32 nonaka DELAY(1); 3960 1.58 nat } 3961 1.32 nonaka 3962 1.58 nat if (ISSET(sc->chip, URTWN_CHIP_92EU)) { 3963 1.58 nat crystalcap = sc->r88e_rom[0xb9]; 3964 1.58 nat if (crystalcap == 0x00) 3965 1.58 nat crystalcap = 0x20; 3966 1.58 nat crystalcap &= 0x3f; 3967 1.58 nat reg = urtwn_bb_read(sc, R92C_AFE_CTRL3); 3968 1.58 nat urtwn_bb_write(sc, R92C_AFE_CTRL3, 3969 1.58 nat RW(reg, R92C_AFE_XTAL_CTRL_ADDR, 3970 1.58 nat crystalcap | crystalcap << 6)); 3971 1.58 nat urtwn_write_4(sc, R92C_AFE_XTAL_CTRL, 0xf81fb); 3972 1.58 nat } else if (ISSET(sc->chip, URTWN_CHIP_88E)) { 3973 1.32 nonaka crystalcap = sc->r88e_rom[0xb9]; 3974 1.32 nonaka if (crystalcap == 0xff) 3975 1.32 nonaka crystalcap = 0x20; 3976 1.32 nonaka crystalcap &= 0x3f; 3977 1.32 nonaka reg = urtwn_bb_read(sc, R92C_AFE_XTAL_CTRL); 3978 1.32 nonaka urtwn_bb_write(sc, R92C_AFE_XTAL_CTRL, 3979 1.32 nonaka RW(reg, R92C_AFE_XTAL_CTRL_ADDR, 3980 1.32 nonaka crystalcap | crystalcap << 6)); 3981 1.32 nonaka } else { 3982 1.32 nonaka if (urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) & 3983 1.32 nonaka R92C_HSSI_PARAM2_CCK_HIPWR) { 3984 1.32 nonaka SET(sc->sc_flags, URTWN_FLAG_CCK_HIPWR); 3985 1.32 nonaka } 3986 1.1 nonaka } 3987 1.1 nonaka } 3988 1.1 nonaka 3989 1.88 jdolecek static void __noinline 3990 1.1 nonaka urtwn_rf_init(struct urtwn_softc *sc) 3991 1.1 nonaka { 3992 1.60 thorpej const struct rtwn_rf_prog *prog; 3993 1.1 nonaka uint32_t reg, mask, saved; 3994 1.22 christos size_t i, j, idx; 3995 1.1 nonaka 3996 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 3997 1.1 nonaka 3998 1.1 nonaka /* Select RF programming based on board type. */ 3999 1.32 nonaka if (ISSET(sc->chip, URTWN_CHIP_88E)) 4000 1.32 nonaka prog = rtl8188eu_rf_prog; 4001 1.49 nat else if (ISSET(sc->chip, URTWN_CHIP_92EU)) 4002 1.49 nat prog = rtl8192eu_rf_prog; 4003 1.32 nonaka else if (!(sc->chip & URTWN_CHIP_92C)) { 4004 1.1 nonaka if (sc->board_type == R92C_BOARD_TYPE_MINICARD) { 4005 1.1 nonaka prog = rtl8188ce_rf_prog; 4006 1.1 nonaka } else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA) { 4007 1.1 nonaka prog = rtl8188ru_rf_prog; 4008 1.1 nonaka } else { 4009 1.1 nonaka prog = rtl8188cu_rf_prog; 4010 1.1 nonaka } 4011 1.1 nonaka } else { 4012 1.1 nonaka prog = rtl8192ce_rf_prog; 4013 1.1 nonaka } 4014 1.1 nonaka 4015 1.1 nonaka for (i = 0; i < sc->nrxchains; i++) { 4016 1.1 nonaka /* Save RF_ENV control type. */ 4017 1.1 nonaka idx = i / 2; 4018 1.1 nonaka mask = 0xffffU << ((i % 2) * 16); 4019 1.1 nonaka saved = urtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx)) & mask; 4020 1.1 nonaka 4021 1.1 nonaka /* Set RF_ENV enable. */ 4022 1.1 nonaka reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i)); 4023 1.1 nonaka reg |= 0x100000; 4024 1.1 nonaka urtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg); 4025 1.49 nat DELAY(50); 4026 1.1 nonaka 4027 1.1 nonaka /* Set RF_ENV output high. */ 4028 1.1 nonaka reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i)); 4029 1.1 nonaka reg |= 0x10; 4030 1.1 nonaka urtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg); 4031 1.49 nat DELAY(50); 4032 1.1 nonaka 4033 1.1 nonaka /* Set address and data lengths of RF registers. */ 4034 1.1 nonaka reg = urtwn_bb_read(sc, R92C_HSSI_PARAM2(i)); 4035 1.1 nonaka reg &= ~R92C_HSSI_PARAM2_ADDR_LENGTH; 4036 1.1 nonaka urtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg); 4037 1.49 nat DELAY(50); 4038 1.1 nonaka reg = urtwn_bb_read(sc, R92C_HSSI_PARAM2(i)); 4039 1.1 nonaka reg &= ~R92C_HSSI_PARAM2_DATA_LENGTH; 4040 1.1 nonaka urtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg); 4041 1.49 nat DELAY(50); 4042 1.1 nonaka 4043 1.1 nonaka /* Write RF initialization values for this chain. */ 4044 1.1 nonaka for (j = 0; j < prog[i].count; j++) { 4045 1.1 nonaka if (prog[i].regs[j] >= 0xf9 && 4046 1.1 nonaka prog[i].regs[j] <= 0xfe) { 4047 1.1 nonaka /* 4048 1.1 nonaka * These are fake RF registers offsets that 4049 1.1 nonaka * indicate a delay is required. 4050 1.1 nonaka */ 4051 1.49 nat urtwn_delay_ms(sc, 50); 4052 1.1 nonaka continue; 4053 1.1 nonaka } 4054 1.1 nonaka urtwn_rf_write(sc, i, prog[i].regs[j], prog[i].vals[j]); 4055 1.49 nat DELAY(5); 4056 1.1 nonaka } 4057 1.1 nonaka 4058 1.1 nonaka /* Restore RF_ENV control type. */ 4059 1.1 nonaka reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx)) & ~mask; 4060 1.1 nonaka urtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(idx), reg | saved); 4061 1.1 nonaka } 4062 1.1 nonaka 4063 1.1 nonaka if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) == 4064 1.1 nonaka URTWN_CHIP_UMC_A_CUT) { 4065 1.1 nonaka urtwn_rf_write(sc, 0, R92C_RF_RX_G1, 0x30255); 4066 1.1 nonaka urtwn_rf_write(sc, 0, R92C_RF_RX_G2, 0x50a00); 4067 1.1 nonaka } 4068 1.1 nonaka 4069 1.1 nonaka /* Cache RF register CHNLBW. */ 4070 1.1 nonaka for (i = 0; i < 2; i++) { 4071 1.1 nonaka sc->rf_chnlbw[i] = urtwn_rf_read(sc, i, R92C_RF_CHNLBW); 4072 1.1 nonaka } 4073 1.1 nonaka } 4074 1.1 nonaka 4075 1.88 jdolecek static void __noinline 4076 1.1 nonaka urtwn_cam_init(struct urtwn_softc *sc) 4077 1.1 nonaka { 4078 1.1 nonaka uint32_t content, command; 4079 1.1 nonaka uint8_t idx; 4080 1.22 christos size_t i; 4081 1.1 nonaka 4082 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 4083 1.1 nonaka 4084 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 4085 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_92EU)) 4086 1.49 nat return; 4087 1.12 christos 4088 1.1 nonaka for (idx = 0; idx < R92C_CAM_ENTRY_COUNT; idx++) { 4089 1.1 nonaka content = (idx & 3) 4090 1.1 nonaka | (R92C_CAM_ALGO_AES << R92C_CAM_ALGO_S) 4091 1.1 nonaka | R92C_CAM_VALID; 4092 1.1 nonaka 4093 1.1 nonaka command = R92C_CAMCMD_POLLING 4094 1.1 nonaka | R92C_CAMCMD_WRITE 4095 1.1 nonaka | R92C_CAM_CTL0(idx); 4096 1.1 nonaka 4097 1.1 nonaka urtwn_write_4(sc, R92C_CAMWRITE, content); 4098 1.1 nonaka urtwn_write_4(sc, R92C_CAMCMD, command); 4099 1.1 nonaka } 4100 1.1 nonaka 4101 1.1 nonaka for (idx = 0; idx < R92C_CAM_ENTRY_COUNT; idx++) { 4102 1.1 nonaka for (i = 0; i < /* CAM_CONTENT_COUNT */ 8; i++) { 4103 1.1 nonaka if (i == 0) { 4104 1.1 nonaka content = (idx & 3) 4105 1.1 nonaka | (R92C_CAM_ALGO_AES << R92C_CAM_ALGO_S) 4106 1.1 nonaka | R92C_CAM_VALID; 4107 1.1 nonaka } else { 4108 1.1 nonaka content = 0; 4109 1.1 nonaka } 4110 1.1 nonaka 4111 1.1 nonaka command = R92C_CAMCMD_POLLING 4112 1.1 nonaka | R92C_CAMCMD_WRITE 4113 1.1 nonaka | R92C_CAM_CTL0(idx) 4114 1.22 christos | i; 4115 1.1 nonaka 4116 1.1 nonaka urtwn_write_4(sc, R92C_CAMWRITE, content); 4117 1.1 nonaka urtwn_write_4(sc, R92C_CAMCMD, command); 4118 1.1 nonaka } 4119 1.1 nonaka } 4120 1.1 nonaka 4121 1.1 nonaka /* Invalidate all CAM entries. */ 4122 1.1 nonaka urtwn_write_4(sc, R92C_CAMCMD, R92C_CAMCMD_POLLING | R92C_CAMCMD_CLR); 4123 1.1 nonaka } 4124 1.1 nonaka 4125 1.88 jdolecek static void __noinline 4126 1.1 nonaka urtwn_pa_bias_init(struct urtwn_softc *sc) 4127 1.1 nonaka { 4128 1.1 nonaka uint8_t reg; 4129 1.22 christos size_t i; 4130 1.1 nonaka 4131 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 4132 1.1 nonaka 4133 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 4134 1.12 christos 4135 1.1 nonaka for (i = 0; i < sc->nrxchains; i++) { 4136 1.1 nonaka if (sc->pa_setting & (1U << i)) 4137 1.1 nonaka continue; 4138 1.1 nonaka 4139 1.1 nonaka urtwn_rf_write(sc, i, R92C_RF_IPA, 0x0f406); 4140 1.1 nonaka urtwn_rf_write(sc, i, R92C_RF_IPA, 0x4f406); 4141 1.1 nonaka urtwn_rf_write(sc, i, R92C_RF_IPA, 0x8f406); 4142 1.1 nonaka urtwn_rf_write(sc, i, R92C_RF_IPA, 0xcf406); 4143 1.1 nonaka } 4144 1.1 nonaka if (!(sc->pa_setting & 0x10)) { 4145 1.1 nonaka reg = urtwn_read_1(sc, 0x16); 4146 1.1 nonaka reg = (reg & ~0xf0) | 0x90; 4147 1.1 nonaka urtwn_write_1(sc, 0x16, reg); 4148 1.1 nonaka } 4149 1.1 nonaka } 4150 1.1 nonaka 4151 1.88 jdolecek static void __noinline 4152 1.1 nonaka urtwn_rxfilter_init(struct urtwn_softc *sc) 4153 1.1 nonaka { 4154 1.1 nonaka 4155 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 4156 1.1 nonaka 4157 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 4158 1.12 christos 4159 1.1 nonaka /* Initialize Rx filter. */ 4160 1.1 nonaka /* TODO: use better filter for monitor mode. */ 4161 1.1 nonaka urtwn_write_4(sc, R92C_RCR, 4162 1.1 nonaka R92C_RCR_AAP | R92C_RCR_APM | R92C_RCR_AM | R92C_RCR_AB | 4163 1.1 nonaka R92C_RCR_APP_ICV | R92C_RCR_AMF | R92C_RCR_HTC_LOC_CTRL | 4164 1.1 nonaka R92C_RCR_APP_MIC | R92C_RCR_APP_PHYSTS); 4165 1.1 nonaka /* Accept all multicast frames. */ 4166 1.1 nonaka urtwn_write_4(sc, R92C_MAR + 0, 0xffffffff); 4167 1.1 nonaka urtwn_write_4(sc, R92C_MAR + 4, 0xffffffff); 4168 1.1 nonaka /* Accept all management frames. */ 4169 1.1 nonaka urtwn_write_2(sc, R92C_RXFLTMAP0, 0xffff); 4170 1.1 nonaka /* Reject all control frames. */ 4171 1.1 nonaka urtwn_write_2(sc, R92C_RXFLTMAP1, 0x0000); 4172 1.1 nonaka /* Accept all data frames. */ 4173 1.1 nonaka urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff); 4174 1.1 nonaka } 4175 1.1 nonaka 4176 1.88 jdolecek static void __noinline 4177 1.1 nonaka urtwn_edca_init(struct urtwn_softc *sc) 4178 1.1 nonaka { 4179 1.1 nonaka 4180 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 4181 1.1 nonaka 4182 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 4183 1.12 christos 4184 1.1 nonaka /* set spec SIFS (used in NAV) */ 4185 1.1 nonaka urtwn_write_2(sc, R92C_SPEC_SIFS, 0x100a); 4186 1.1 nonaka urtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x100a); 4187 1.1 nonaka 4188 1.1 nonaka /* set SIFS CCK/OFDM */ 4189 1.1 nonaka urtwn_write_2(sc, R92C_SIFS_CCK, 0x100a); 4190 1.1 nonaka urtwn_write_2(sc, R92C_SIFS_OFDM, 0x100a); 4191 1.1 nonaka 4192 1.1 nonaka /* TXOP */ 4193 1.1 nonaka urtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x005ea42b); 4194 1.1 nonaka urtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a44f); 4195 1.1 nonaka urtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005ea324); 4196 1.1 nonaka urtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002fa226); 4197 1.1 nonaka } 4198 1.1 nonaka 4199 1.1 nonaka static void 4200 1.1 nonaka urtwn_write_txpower(struct urtwn_softc *sc, int chain, 4201 1.1 nonaka uint16_t power[URTWN_RIDX_COUNT]) 4202 1.1 nonaka { 4203 1.1 nonaka uint32_t reg; 4204 1.1 nonaka 4205 1.74 gson URTWNHIST_FUNC(); 4206 1.74 gson URTWNHIST_CALLARGS("chain=%jd", chain, 0, 0, 0); 4207 1.1 nonaka 4208 1.1 nonaka /* Write per-CCK rate Tx power. */ 4209 1.1 nonaka if (chain == 0) { 4210 1.1 nonaka reg = urtwn_bb_read(sc, R92C_TXAGC_A_CCK1_MCS32); 4211 1.1 nonaka reg = RW(reg, R92C_TXAGC_A_CCK1, power[0]); 4212 1.1 nonaka urtwn_bb_write(sc, R92C_TXAGC_A_CCK1_MCS32, reg); 4213 1.1 nonaka 4214 1.1 nonaka reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11); 4215 1.1 nonaka reg = RW(reg, R92C_TXAGC_A_CCK2, power[1]); 4216 1.1 nonaka reg = RW(reg, R92C_TXAGC_A_CCK55, power[2]); 4217 1.1 nonaka reg = RW(reg, R92C_TXAGC_A_CCK11, power[3]); 4218 1.1 nonaka urtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg); 4219 1.1 nonaka } else { 4220 1.1 nonaka reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK1_55_MCS32); 4221 1.1 nonaka reg = RW(reg, R92C_TXAGC_B_CCK1, power[0]); 4222 1.1 nonaka reg = RW(reg, R92C_TXAGC_B_CCK2, power[1]); 4223 1.1 nonaka reg = RW(reg, R92C_TXAGC_B_CCK55, power[2]); 4224 1.1 nonaka urtwn_bb_write(sc, R92C_TXAGC_B_CCK1_55_MCS32, reg); 4225 1.1 nonaka 4226 1.1 nonaka reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11); 4227 1.1 nonaka reg = RW(reg, R92C_TXAGC_B_CCK11, power[3]); 4228 1.1 nonaka urtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg); 4229 1.1 nonaka } 4230 1.1 nonaka /* Write per-OFDM rate Tx power. */ 4231 1.1 nonaka urtwn_bb_write(sc, R92C_TXAGC_RATE18_06(chain), 4232 1.1 nonaka SM(R92C_TXAGC_RATE06, power[ 4]) | 4233 1.1 nonaka SM(R92C_TXAGC_RATE09, power[ 5]) | 4234 1.1 nonaka SM(R92C_TXAGC_RATE12, power[ 6]) | 4235 1.1 nonaka SM(R92C_TXAGC_RATE18, power[ 7])); 4236 1.1 nonaka urtwn_bb_write(sc, R92C_TXAGC_RATE54_24(chain), 4237 1.1 nonaka SM(R92C_TXAGC_RATE24, power[ 8]) | 4238 1.1 nonaka SM(R92C_TXAGC_RATE36, power[ 9]) | 4239 1.1 nonaka SM(R92C_TXAGC_RATE48, power[10]) | 4240 1.1 nonaka SM(R92C_TXAGC_RATE54, power[11])); 4241 1.1 nonaka /* Write per-MCS Tx power. */ 4242 1.1 nonaka urtwn_bb_write(sc, R92C_TXAGC_MCS03_MCS00(chain), 4243 1.1 nonaka SM(R92C_TXAGC_MCS00, power[12]) | 4244 1.1 nonaka SM(R92C_TXAGC_MCS01, power[13]) | 4245 1.1 nonaka SM(R92C_TXAGC_MCS02, power[14]) | 4246 1.1 nonaka SM(R92C_TXAGC_MCS03, power[15])); 4247 1.1 nonaka urtwn_bb_write(sc, R92C_TXAGC_MCS07_MCS04(chain), 4248 1.1 nonaka SM(R92C_TXAGC_MCS04, power[16]) | 4249 1.1 nonaka SM(R92C_TXAGC_MCS05, power[17]) | 4250 1.1 nonaka SM(R92C_TXAGC_MCS06, power[18]) | 4251 1.1 nonaka SM(R92C_TXAGC_MCS07, power[19])); 4252 1.1 nonaka urtwn_bb_write(sc, R92C_TXAGC_MCS11_MCS08(chain), 4253 1.1 nonaka SM(R92C_TXAGC_MCS08, power[20]) | 4254 1.1 nonaka SM(R92C_TXAGC_MCS09, power[21]) | 4255 1.1 nonaka SM(R92C_TXAGC_MCS10, power[22]) | 4256 1.1 nonaka SM(R92C_TXAGC_MCS11, power[23])); 4257 1.1 nonaka urtwn_bb_write(sc, R92C_TXAGC_MCS15_MCS12(chain), 4258 1.1 nonaka SM(R92C_TXAGC_MCS12, power[24]) | 4259 1.1 nonaka SM(R92C_TXAGC_MCS13, power[25]) | 4260 1.1 nonaka SM(R92C_TXAGC_MCS14, power[26]) | 4261 1.1 nonaka SM(R92C_TXAGC_MCS15, power[27])); 4262 1.1 nonaka } 4263 1.1 nonaka 4264 1.1 nonaka static void 4265 1.22 christos urtwn_get_txpower(struct urtwn_softc *sc, size_t chain, u_int chan, u_int ht40m, 4266 1.1 nonaka uint16_t power[URTWN_RIDX_COUNT]) 4267 1.1 nonaka { 4268 1.1 nonaka struct r92c_rom *rom = &sc->rom; 4269 1.1 nonaka uint16_t cckpow, ofdmpow, htpow, diff, maxpow; 4270 1.60 thorpej const struct rtwn_txpwr *base; 4271 1.1 nonaka int ridx, group; 4272 1.1 nonaka 4273 1.74 gson URTWNHIST_FUNC(); 4274 1.74 gson URTWNHIST_CALLARGS("chain=%jd, chan=%jd", chain, chan, 0, 0); 4275 1.1 nonaka 4276 1.1 nonaka /* Determine channel group. */ 4277 1.1 nonaka if (chan <= 3) { 4278 1.1 nonaka group = 0; 4279 1.1 nonaka } else if (chan <= 9) { 4280 1.1 nonaka group = 1; 4281 1.1 nonaka } else { 4282 1.1 nonaka group = 2; 4283 1.1 nonaka } 4284 1.1 nonaka 4285 1.1 nonaka /* Get original Tx power based on board type and RF chain. */ 4286 1.1 nonaka if (!(sc->chip & URTWN_CHIP_92C)) { 4287 1.1 nonaka if (sc->board_type == R92C_BOARD_TYPE_HIGHPA) { 4288 1.1 nonaka base = &rtl8188ru_txagc[chain]; 4289 1.1 nonaka } else { 4290 1.1 nonaka base = &rtl8192cu_txagc[chain]; 4291 1.1 nonaka } 4292 1.1 nonaka } else { 4293 1.1 nonaka base = &rtl8192cu_txagc[chain]; 4294 1.1 nonaka } 4295 1.1 nonaka 4296 1.1 nonaka memset(power, 0, URTWN_RIDX_COUNT * sizeof(power[0])); 4297 1.1 nonaka if (sc->regulatory == 0) { 4298 1.1 nonaka for (ridx = 0; ridx <= 3; ridx++) { 4299 1.1 nonaka power[ridx] = base->pwr[0][ridx]; 4300 1.1 nonaka } 4301 1.1 nonaka } 4302 1.1 nonaka for (ridx = 4; ridx < URTWN_RIDX_COUNT; ridx++) { 4303 1.1 nonaka if (sc->regulatory == 3) { 4304 1.1 nonaka power[ridx] = base->pwr[0][ridx]; 4305 1.1 nonaka /* Apply vendor limits. */ 4306 1.1 nonaka if (ht40m != IEEE80211_HTINFO_2NDCHAN_NONE) { 4307 1.1 nonaka maxpow = rom->ht40_max_pwr[group]; 4308 1.1 nonaka } else { 4309 1.1 nonaka maxpow = rom->ht20_max_pwr[group]; 4310 1.1 nonaka } 4311 1.1 nonaka maxpow = (maxpow >> (chain * 4)) & 0xf; 4312 1.1 nonaka if (power[ridx] > maxpow) { 4313 1.1 nonaka power[ridx] = maxpow; 4314 1.1 nonaka } 4315 1.1 nonaka } else if (sc->regulatory == 1) { 4316 1.1 nonaka if (ht40m == IEEE80211_HTINFO_2NDCHAN_NONE) { 4317 1.1 nonaka power[ridx] = base->pwr[group][ridx]; 4318 1.1 nonaka } 4319 1.1 nonaka } else if (sc->regulatory != 2) { 4320 1.1 nonaka power[ridx] = base->pwr[0][ridx]; 4321 1.1 nonaka } 4322 1.1 nonaka } 4323 1.1 nonaka 4324 1.1 nonaka /* Compute per-CCK rate Tx power. */ 4325 1.1 nonaka cckpow = rom->cck_tx_pwr[chain][group]; 4326 1.1 nonaka for (ridx = 0; ridx <= 3; ridx++) { 4327 1.1 nonaka power[ridx] += cckpow; 4328 1.1 nonaka if (power[ridx] > R92C_MAX_TX_PWR) { 4329 1.1 nonaka power[ridx] = R92C_MAX_TX_PWR; 4330 1.1 nonaka } 4331 1.1 nonaka } 4332 1.1 nonaka 4333 1.1 nonaka htpow = rom->ht40_1s_tx_pwr[chain][group]; 4334 1.1 nonaka if (sc->ntxchains > 1) { 4335 1.1 nonaka /* Apply reduction for 2 spatial streams. */ 4336 1.1 nonaka diff = rom->ht40_2s_tx_pwr_diff[group]; 4337 1.1 nonaka diff = (diff >> (chain * 4)) & 0xf; 4338 1.1 nonaka htpow = (htpow > diff) ? htpow - diff : 0; 4339 1.1 nonaka } 4340 1.1 nonaka 4341 1.1 nonaka /* Compute per-OFDM rate Tx power. */ 4342 1.1 nonaka diff = rom->ofdm_tx_pwr_diff[group]; 4343 1.1 nonaka diff = (diff >> (chain * 4)) & 0xf; 4344 1.1 nonaka ofdmpow = htpow + diff; /* HT->OFDM correction. */ 4345 1.1 nonaka for (ridx = 4; ridx <= 11; ridx++) { 4346 1.1 nonaka power[ridx] += ofdmpow; 4347 1.1 nonaka if (power[ridx] > R92C_MAX_TX_PWR) { 4348 1.1 nonaka power[ridx] = R92C_MAX_TX_PWR; 4349 1.1 nonaka } 4350 1.1 nonaka } 4351 1.1 nonaka 4352 1.1 nonaka /* Compute per-MCS Tx power. */ 4353 1.1 nonaka if (ht40m == IEEE80211_HTINFO_2NDCHAN_NONE) { 4354 1.1 nonaka diff = rom->ht20_tx_pwr_diff[group]; 4355 1.1 nonaka diff = (diff >> (chain * 4)) & 0xf; 4356 1.1 nonaka htpow += diff; /* HT40->HT20 correction. */ 4357 1.1 nonaka } 4358 1.1 nonaka for (ridx = 12; ridx < URTWN_RIDX_COUNT; ridx++) { 4359 1.1 nonaka power[ridx] += htpow; 4360 1.1 nonaka if (power[ridx] > R92C_MAX_TX_PWR) { 4361 1.1 nonaka power[ridx] = R92C_MAX_TX_PWR; 4362 1.1 nonaka } 4363 1.1 nonaka } 4364 1.1 nonaka #ifdef URTWN_DEBUG 4365 1.1 nonaka if (urtwn_debug & DBG_RF) { 4366 1.1 nonaka /* Dump per-rate Tx power values. */ 4367 1.74 gson DPRINTFN(DBG_RF, "Tx power for chain %jd:", chain, 0, 0, 0); 4368 1.74 gson for (ridx = 0; ridx < URTWN_RIDX_COUNT; ridx++) 4369 1.74 gson DPRINTFN(DBG_RF, "Rate %jd = %ju", ridx, power[ridx], 0, 0); 4370 1.1 nonaka } 4371 1.1 nonaka #endif 4372 1.1 nonaka } 4373 1.1 nonaka 4374 1.32 nonaka void 4375 1.32 nonaka urtwn_r88e_get_txpower(struct urtwn_softc *sc, size_t chain, u_int chan, 4376 1.32 nonaka u_int ht40m, uint16_t power[URTWN_RIDX_COUNT]) 4377 1.32 nonaka { 4378 1.32 nonaka uint16_t cckpow, ofdmpow, bw20pow, htpow; 4379 1.60 thorpej const struct rtwn_r88e_txpwr *base; 4380 1.32 nonaka int ridx, group; 4381 1.32 nonaka 4382 1.74 gson URTWNHIST_FUNC(); 4383 1.74 gson URTWNHIST_CALLARGS("chain=%jd, chan=%jd", chain, chan, 0, 0); 4384 1.32 nonaka 4385 1.32 nonaka /* Determine channel group. */ 4386 1.32 nonaka if (chan <= 2) 4387 1.32 nonaka group = 0; 4388 1.32 nonaka else if (chan <= 5) 4389 1.32 nonaka group = 1; 4390 1.32 nonaka else if (chan <= 8) 4391 1.32 nonaka group = 2; 4392 1.32 nonaka else if (chan <= 11) 4393 1.32 nonaka group = 3; 4394 1.32 nonaka else if (chan <= 13) 4395 1.32 nonaka group = 4; 4396 1.32 nonaka else 4397 1.32 nonaka group = 5; 4398 1.32 nonaka 4399 1.32 nonaka /* Get original Tx power based on board type and RF chain. */ 4400 1.32 nonaka base = &rtl8188eu_txagc[chain]; 4401 1.32 nonaka 4402 1.32 nonaka memset(power, 0, URTWN_RIDX_COUNT * sizeof(power[0])); 4403 1.32 nonaka if (sc->regulatory == 0) { 4404 1.32 nonaka for (ridx = 0; ridx <= 3; ridx++) 4405 1.32 nonaka power[ridx] = base->pwr[0][ridx]; 4406 1.32 nonaka } 4407 1.32 nonaka for (ridx = 4; ridx < URTWN_RIDX_COUNT; ridx++) { 4408 1.32 nonaka if (sc->regulatory == 3) 4409 1.32 nonaka power[ridx] = base->pwr[0][ridx]; 4410 1.32 nonaka else if (sc->regulatory == 1) { 4411 1.32 nonaka if (ht40m == IEEE80211_HTINFO_2NDCHAN_NONE) 4412 1.32 nonaka power[ridx] = base->pwr[group][ridx]; 4413 1.32 nonaka } else if (sc->regulatory != 2) 4414 1.32 nonaka power[ridx] = base->pwr[0][ridx]; 4415 1.32 nonaka } 4416 1.32 nonaka 4417 1.32 nonaka /* Compute per-CCK rate Tx power. */ 4418 1.32 nonaka cckpow = sc->cck_tx_pwr[group]; 4419 1.32 nonaka for (ridx = 0; ridx <= 3; ridx++) { 4420 1.32 nonaka power[ridx] += cckpow; 4421 1.32 nonaka if (power[ridx] > R92C_MAX_TX_PWR) 4422 1.32 nonaka power[ridx] = R92C_MAX_TX_PWR; 4423 1.32 nonaka } 4424 1.32 nonaka 4425 1.32 nonaka htpow = sc->ht40_tx_pwr[group]; 4426 1.32 nonaka 4427 1.32 nonaka /* Compute per-OFDM rate Tx power. */ 4428 1.32 nonaka ofdmpow = htpow + sc->ofdm_tx_pwr_diff; 4429 1.32 nonaka for (ridx = 4; ridx <= 11; ridx++) { 4430 1.32 nonaka power[ridx] += ofdmpow; 4431 1.32 nonaka if (power[ridx] > R92C_MAX_TX_PWR) 4432 1.32 nonaka power[ridx] = R92C_MAX_TX_PWR; 4433 1.32 nonaka } 4434 1.32 nonaka 4435 1.32 nonaka bw20pow = htpow + sc->bw20_tx_pwr_diff; 4436 1.32 nonaka for (ridx = 12; ridx <= 27; ridx++) { 4437 1.32 nonaka power[ridx] += bw20pow; 4438 1.32 nonaka if (power[ridx] > R92C_MAX_TX_PWR) 4439 1.32 nonaka power[ridx] = R92C_MAX_TX_PWR; 4440 1.32 nonaka } 4441 1.32 nonaka } 4442 1.32 nonaka 4443 1.1 nonaka static void 4444 1.1 nonaka urtwn_set_txpower(struct urtwn_softc *sc, u_int chan, u_int ht40m) 4445 1.1 nonaka { 4446 1.1 nonaka uint16_t power[URTWN_RIDX_COUNT]; 4447 1.22 christos size_t i; 4448 1.1 nonaka 4449 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 4450 1.1 nonaka 4451 1.1 nonaka for (i = 0; i < sc->ntxchains; i++) { 4452 1.1 nonaka /* Compute per-rate Tx power values. */ 4453 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_88E) || 4454 1.49 nat ISSET(sc->chip, URTWN_CHIP_92EU)) 4455 1.32 nonaka urtwn_r88e_get_txpower(sc, i, chan, ht40m, power); 4456 1.32 nonaka else 4457 1.32 nonaka urtwn_get_txpower(sc, i, chan, ht40m, power); 4458 1.1 nonaka /* Write per-rate Tx power values to hardware. */ 4459 1.1 nonaka urtwn_write_txpower(sc, i, power); 4460 1.1 nonaka } 4461 1.1 nonaka } 4462 1.1 nonaka 4463 1.88 jdolecek static void __noinline 4464 1.1 nonaka urtwn_set_chan(struct urtwn_softc *sc, struct ieee80211_channel *c, u_int ht40m) 4465 1.1 nonaka { 4466 1.1 nonaka struct ieee80211com *ic = &sc->sc_ic; 4467 1.1 nonaka u_int chan; 4468 1.22 christos size_t i; 4469 1.1 nonaka 4470 1.1 nonaka chan = ieee80211_chan2ieee(ic, c); /* XXX center freq! */ 4471 1.1 nonaka 4472 1.74 gson URTWNHIST_FUNC(); 4473 1.74 gson URTWNHIST_CALLARGS("chan=%jd", chan, 0, 0, 0); 4474 1.1 nonaka 4475 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 4476 1.12 christos 4477 1.1 nonaka if (ht40m == IEEE80211_HTINFO_2NDCHAN_ABOVE) { 4478 1.1 nonaka chan += 2; 4479 1.1 nonaka } else if (ht40m == IEEE80211_HTINFO_2NDCHAN_BELOW){ 4480 1.1 nonaka chan -= 2; 4481 1.1 nonaka } 4482 1.1 nonaka 4483 1.1 nonaka /* Set Tx power for this new channel. */ 4484 1.1 nonaka urtwn_set_txpower(sc, chan, ht40m); 4485 1.1 nonaka 4486 1.1 nonaka for (i = 0; i < sc->nrxchains; i++) { 4487 1.1 nonaka urtwn_rf_write(sc, i, R92C_RF_CHNLBW, 4488 1.1 nonaka RW(sc->rf_chnlbw[i], R92C_RF_CHNLBW_CHNL, chan)); 4489 1.1 nonaka } 4490 1.1 nonaka 4491 1.1 nonaka if (ht40m) { 4492 1.1 nonaka /* Is secondary channel below or above primary? */ 4493 1.1 nonaka int prichlo = (ht40m == IEEE80211_HTINFO_2NDCHAN_ABOVE); 4494 1.1 nonaka uint32_t reg; 4495 1.1 nonaka 4496 1.1 nonaka urtwn_write_1(sc, R92C_BWOPMODE, 4497 1.1 nonaka urtwn_read_1(sc, R92C_BWOPMODE) & ~R92C_BWOPMODE_20MHZ); 4498 1.1 nonaka 4499 1.1 nonaka reg = urtwn_read_1(sc, R92C_RRSR + 2); 4500 1.1 nonaka reg = (reg & ~0x6f) | (prichlo ? 1 : 2) << 5; 4501 1.1 nonaka urtwn_write_1(sc, R92C_RRSR + 2, (uint8_t)reg); 4502 1.1 nonaka 4503 1.1 nonaka urtwn_bb_write(sc, R92C_FPGA0_RFMOD, 4504 1.1 nonaka urtwn_bb_read(sc, R92C_FPGA0_RFMOD) | R92C_RFMOD_40MHZ); 4505 1.1 nonaka urtwn_bb_write(sc, R92C_FPGA1_RFMOD, 4506 1.1 nonaka urtwn_bb_read(sc, R92C_FPGA1_RFMOD) | R92C_RFMOD_40MHZ); 4507 1.1 nonaka 4508 1.1 nonaka /* Set CCK side band. */ 4509 1.1 nonaka reg = urtwn_bb_read(sc, R92C_CCK0_SYSTEM); 4510 1.1 nonaka reg = (reg & ~0x00000010) | (prichlo ? 0 : 1) << 4; 4511 1.1 nonaka urtwn_bb_write(sc, R92C_CCK0_SYSTEM, reg); 4512 1.1 nonaka 4513 1.1 nonaka reg = urtwn_bb_read(sc, R92C_OFDM1_LSTF); 4514 1.1 nonaka reg = (reg & ~0x00000c00) | (prichlo ? 1 : 2) << 10; 4515 1.1 nonaka urtwn_bb_write(sc, R92C_OFDM1_LSTF, reg); 4516 1.1 nonaka 4517 1.1 nonaka urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2, 4518 1.1 nonaka urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) & 4519 1.1 nonaka ~R92C_FPGA0_ANAPARAM2_CBW20); 4520 1.1 nonaka 4521 1.1 nonaka reg = urtwn_bb_read(sc, 0x818); 4522 1.1 nonaka reg = (reg & ~0x0c000000) | (prichlo ? 2 : 1) << 26; 4523 1.1 nonaka urtwn_bb_write(sc, 0x818, reg); 4524 1.1 nonaka 4525 1.1 nonaka /* Select 40MHz bandwidth. */ 4526 1.1 nonaka urtwn_rf_write(sc, 0, R92C_RF_CHNLBW, 4527 1.1 nonaka (sc->rf_chnlbw[0] & ~0xfff) | chan); 4528 1.1 nonaka } else { 4529 1.1 nonaka urtwn_write_1(sc, R92C_BWOPMODE, 4530 1.1 nonaka urtwn_read_1(sc, R92C_BWOPMODE) | R92C_BWOPMODE_20MHZ); 4531 1.1 nonaka 4532 1.1 nonaka urtwn_bb_write(sc, R92C_FPGA0_RFMOD, 4533 1.1 nonaka urtwn_bb_read(sc, R92C_FPGA0_RFMOD) & ~R92C_RFMOD_40MHZ); 4534 1.1 nonaka urtwn_bb_write(sc, R92C_FPGA1_RFMOD, 4535 1.1 nonaka urtwn_bb_read(sc, R92C_FPGA1_RFMOD) & ~R92C_RFMOD_40MHZ); 4536 1.1 nonaka 4537 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_88E) && 4538 1.49 nat !ISSET(sc->chip, URTWN_CHIP_92EU)) { 4539 1.32 nonaka urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2, 4540 1.32 nonaka urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) | 4541 1.32 nonaka R92C_FPGA0_ANAPARAM2_CBW20); 4542 1.32 nonaka } 4543 1.1 nonaka 4544 1.1 nonaka /* Select 20MHz bandwidth. */ 4545 1.1 nonaka urtwn_rf_write(sc, 0, R92C_RF_CHNLBW, 4546 1.32 nonaka (sc->rf_chnlbw[0] & ~0xfff) | chan | 4547 1.49 nat (ISSET(sc->chip, URTWN_CHIP_88E) || 4548 1.49 nat ISSET(sc->chip, URTWN_CHIP_92EU) ? 4549 1.32 nonaka R88E_RF_CHNLBW_BW20 : R92C_RF_CHNLBW_BW20)); 4550 1.1 nonaka } 4551 1.1 nonaka } 4552 1.1 nonaka 4553 1.88 jdolecek static void __noinline 4554 1.1 nonaka urtwn_iq_calib(struct urtwn_softc *sc, bool inited) 4555 1.1 nonaka { 4556 1.1 nonaka 4557 1.74 gson URTWNHIST_FUNC(); 4558 1.74 gson URTWNHIST_CALLARGS("inited=%jd", inited, 0, 0, 0); 4559 1.1 nonaka 4560 1.48 nat uint32_t addaBackup[16], iqkBackup[4], piMode; 4561 1.48 nat 4562 1.48 nat #ifdef notyet 4563 1.48 nat uint32_t odfm0_agccore_regs[3]; 4564 1.48 nat uint32_t ant_regs[3]; 4565 1.48 nat uint32_t rf_regs[8]; 4566 1.48 nat #endif 4567 1.48 nat uint32_t reg0, reg1, reg2; 4568 1.48 nat int i, attempt; 4569 1.48 nat 4570 1.48 nat #ifdef notyet 4571 1.48 nat urtwn_write_1(sc, R92E_STBC_SETTING + 2, urtwn_read_1(sc, 4572 1.48 nat R92E_STBC_SETTING + 2)); 4573 1.48 nat urtwn_write_1(sc, R92C_ACLK_MON, 0); 4574 1.48 nat /* Save AGCCORE regs. */ 4575 1.48 nat for (i = 0; i < sc->nrxchains; i++) { 4576 1.48 nat odfm0_agccore_regs[i] = urtwn_read_4(sc, 4577 1.48 nat R92C_OFDM0_AGCCORE1(i)); 4578 1.48 nat } 4579 1.48 nat #endif 4580 1.48 nat /* Save BB regs. */ 4581 1.48 nat reg0 = urtwn_bb_read(sc, R92C_OFDM0_TRXPATHENA); 4582 1.48 nat reg1 = urtwn_bb_read(sc, R92C_OFDM0_TRMUXPAR); 4583 1.48 nat reg2 = urtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(1)); 4584 1.52 skrll 4585 1.48 nat /* Save adda regs to be restored when finished. */ 4586 1.48 nat for (i = 0; i < __arraycount(addaReg); i++) 4587 1.48 nat addaBackup[i] = urtwn_bb_read(sc, addaReg[i]); 4588 1.48 nat /* Save mac regs. */ 4589 1.48 nat iqkBackup[0] = urtwn_read_1(sc, R92C_TXPAUSE); 4590 1.48 nat iqkBackup[1] = urtwn_read_1(sc, R92C_BCN_CTRL); 4591 1.60 thorpej iqkBackup[2] = urtwn_read_1(sc, R92C_BCN_CTRL1); 4592 1.48 nat iqkBackup[3] = urtwn_read_4(sc, R92C_GPIO_MUXCFG); 4593 1.48 nat 4594 1.48 nat #ifdef notyet 4595 1.48 nat ant_regs[0] = urtwn_read_4(sc, R92C_CONFIG_ANT_A); 4596 1.48 nat ant_regs[1] = urtwn_read_4(sc, R92C_CONFIG_ANT_B); 4597 1.48 nat 4598 1.48 nat rf_regs[0] = urtwn_read_4(sc, R92C_FPGA0_RFIFACESW(0)); 4599 1.48 nat for (i = 0; i < sc->nrxchains; i++) 4600 1.48 nat rf_regs[i+1] = urtwn_read_4(sc, R92C_FPGA0_RFIFACEOE(i)); 4601 1.48 nat reg4 = urtwn_read_4(sc, R92C_CCK0_AFESETTING); 4602 1.48 nat #endif 4603 1.48 nat 4604 1.48 nat piMode = (urtwn_bb_read(sc, R92C_HSSI_PARAM1(0)) & 4605 1.48 nat R92C_HSSI_PARAM1_PI); 4606 1.48 nat if (piMode == 0) { 4607 1.48 nat urtwn_bb_write(sc, R92C_HSSI_PARAM1(0), 4608 1.48 nat urtwn_bb_read(sc, R92C_HSSI_PARAM1(0))| 4609 1.48 nat R92C_HSSI_PARAM1_PI); 4610 1.48 nat urtwn_bb_write(sc, R92C_HSSI_PARAM1(1), 4611 1.48 nat urtwn_bb_read(sc, R92C_HSSI_PARAM1(1))| 4612 1.48 nat R92C_HSSI_PARAM1_PI); 4613 1.48 nat } 4614 1.52 skrll 4615 1.48 nat attempt = 1; 4616 1.48 nat 4617 1.48 nat next_attempt: 4618 1.48 nat 4619 1.48 nat /* Set mac regs for calibration. */ 4620 1.48 nat for (i = 0; i < __arraycount(addaReg); i++) { 4621 1.48 nat urtwn_bb_write(sc, addaReg[i], 4622 1.48 nat addaReg[__arraycount(addaReg) - 1]); 4623 1.48 nat } 4624 1.48 nat urtwn_write_2(sc, R92C_CCK0_AFESETTING, urtwn_read_2(sc, 4625 1.48 nat R92C_CCK0_AFESETTING)); 4626 1.48 nat urtwn_write_2(sc, R92C_OFDM0_TRXPATHENA, R92C_IQK_TRXPATHENA); 4627 1.48 nat urtwn_write_2(sc, R92C_OFDM0_TRMUXPAR, R92C_IQK_TRMUXPAR); 4628 1.48 nat urtwn_write_2(sc, R92C_FPGA0_RFIFACESW(1), R92C_IQK_RFIFACESW1); 4629 1.48 nat urtwn_write_4(sc, R92C_LSSI_PARAM(0), R92C_IQK_LSSI_PARAM); 4630 1.48 nat 4631 1.48 nat if (sc->ntxchains > 1) 4632 1.48 nat urtwn_bb_write(sc, R92C_LSSI_PARAM(1), R92C_IQK_LSSI_PARAM); 4633 1.52 skrll 4634 1.60 thorpej urtwn_write_1(sc, R92C_TXPAUSE, (~R92C_TXPAUSE_BCN) & R92C_TXPAUSE_ALL); 4635 1.48 nat urtwn_write_1(sc, R92C_BCN_CTRL, (iqkBackup[1] & 4636 1.48 nat ~R92C_BCN_CTRL_EN_BCN)); 4637 1.60 thorpej urtwn_write_1(sc, R92C_BCN_CTRL1, (iqkBackup[2] & 4638 1.60 thorpej ~R92C_BCN_CTRL_EN_BCN)); 4639 1.48 nat 4640 1.48 nat urtwn_write_1(sc, R92C_GPIO_MUXCFG, (iqkBackup[3] & 4641 1.48 nat ~R92C_GPIO_MUXCFG_ENBT)); 4642 1.48 nat 4643 1.48 nat urtwn_bb_write(sc, R92C_CONFIG_ANT_A, R92C_IQK_CONFIG_ANT); 4644 1.48 nat 4645 1.48 nat if (sc->ntxchains > 1) 4646 1.48 nat urtwn_bb_write(sc, R92C_CONFIG_ANT_B, R92C_IQK_CONFIG_ANT); 4647 1.48 nat urtwn_bb_write(sc, R92C_FPGA0_IQK, R92C_FPGA0_IQK_SETTING); 4648 1.48 nat urtwn_bb_write(sc, R92C_TX_IQK, R92C_TX_IQK_SETTING); 4649 1.48 nat urtwn_bb_write(sc, R92C_RX_IQK, R92C_RX_IQK_SETTING); 4650 1.48 nat 4651 1.48 nat /* Restore BB regs. */ 4652 1.48 nat urtwn_bb_write(sc, R92C_OFDM0_TRXPATHENA, reg0); 4653 1.48 nat urtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(1), reg2); 4654 1.48 nat urtwn_bb_write(sc, R92C_OFDM0_TRMUXPAR, reg1); 4655 1.48 nat 4656 1.48 nat urtwn_bb_write(sc, R92C_FPGA0_IQK, 0x0); 4657 1.48 nat urtwn_bb_write(sc, R92C_LSSI_PARAM(0), R92C_IQK_LSSI_RESTORE); 4658 1.48 nat if (sc->nrxchains > 1) 4659 1.48 nat urtwn_bb_write(sc, R92C_LSSI_PARAM(1), R92C_IQK_LSSI_RESTORE); 4660 1.48 nat 4661 1.48 nat if (attempt-- > 0) 4662 1.48 nat goto next_attempt; 4663 1.48 nat 4664 1.48 nat /* Restore mode. */ 4665 1.48 nat if (piMode == 0) { 4666 1.48 nat urtwn_bb_write(sc, R92C_HSSI_PARAM1(0), 4667 1.48 nat urtwn_bb_read(sc, R92C_HSSI_PARAM1(0)) & 4668 1.48 nat ~R92C_HSSI_PARAM1_PI); 4669 1.48 nat urtwn_bb_write(sc, R92C_HSSI_PARAM1(1), 4670 1.48 nat urtwn_bb_read(sc, R92C_HSSI_PARAM1(1)) & 4671 1.48 nat ~R92C_HSSI_PARAM1_PI); 4672 1.48 nat } 4673 1.48 nat 4674 1.48 nat #ifdef notyet 4675 1.48 nat for (i = 0; i < sc->nrxchains; i++) { 4676 1.48 nat urtwn_write_4(sc, R92C_OFDM0_AGCCORE1(i), 4677 1.48 nat odfm0_agccore_regs[i]); 4678 1.48 nat } 4679 1.48 nat #endif 4680 1.48 nat 4681 1.48 nat /* Restore adda regs. */ 4682 1.48 nat for (i = 0; i < __arraycount(addaReg); i++) 4683 1.48 nat urtwn_bb_write(sc, addaReg[i], addaBackup[i]); 4684 1.48 nat /* Restore mac regs. */ 4685 1.48 nat urtwn_write_1(sc, R92C_TXPAUSE, iqkBackup[0]); 4686 1.48 nat urtwn_write_1(sc, R92C_BCN_CTRL, iqkBackup[1]); 4687 1.48 nat urtwn_write_1(sc, R92C_USTIME_TSF, iqkBackup[2]); 4688 1.48 nat urtwn_write_4(sc, R92C_GPIO_MUXCFG, iqkBackup[3]); 4689 1.48 nat 4690 1.48 nat #ifdef notyet 4691 1.48 nat urtwn_write_4(sc, R92C_CONFIG_ANT_A, ant_regs[0]); 4692 1.48 nat urtwn_write_4(sc, R92C_CONFIG_ANT_B, ant_regs[1]); 4693 1.48 nat 4694 1.48 nat urtwn_write_4(sc, R92C_FPGA0_RFIFACESW(0), rf_regs[0]); 4695 1.48 nat for (i = 0; i < sc->nrxchains; i++) 4696 1.48 nat urtwn_write_4(sc, R92C_FPGA0_RFIFACEOE(i), rf_regs[i+1]); 4697 1.48 nat urtwn_write_4(sc, R92C_CCK0_AFESETTING, reg4); 4698 1.48 nat #endif 4699 1.1 nonaka } 4700 1.1 nonaka 4701 1.1 nonaka static void 4702 1.1 nonaka urtwn_lc_calib(struct urtwn_softc *sc) 4703 1.1 nonaka { 4704 1.1 nonaka uint32_t rf_ac[2]; 4705 1.1 nonaka uint8_t txmode; 4706 1.22 christos size_t i; 4707 1.1 nonaka 4708 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 4709 1.1 nonaka 4710 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 4711 1.12 christos 4712 1.1 nonaka txmode = urtwn_read_1(sc, R92C_OFDM1_LSTF + 3); 4713 1.1 nonaka if ((txmode & 0x70) != 0) { 4714 1.1 nonaka /* Disable all continuous Tx. */ 4715 1.1 nonaka urtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode & ~0x70); 4716 1.1 nonaka 4717 1.1 nonaka /* Set RF mode to standby mode. */ 4718 1.1 nonaka for (i = 0; i < sc->nrxchains; i++) { 4719 1.1 nonaka rf_ac[i] = urtwn_rf_read(sc, i, R92C_RF_AC); 4720 1.1 nonaka urtwn_rf_write(sc, i, R92C_RF_AC, 4721 1.1 nonaka RW(rf_ac[i], R92C_RF_AC_MODE, 4722 1.1 nonaka R92C_RF_AC_MODE_STANDBY)); 4723 1.1 nonaka } 4724 1.1 nonaka } else { 4725 1.1 nonaka /* Block all Tx queues. */ 4726 1.1 nonaka urtwn_write_1(sc, R92C_TXPAUSE, 0xff); 4727 1.1 nonaka } 4728 1.1 nonaka /* Start calibration. */ 4729 1.1 nonaka urtwn_rf_write(sc, 0, R92C_RF_CHNLBW, 4730 1.1 nonaka urtwn_rf_read(sc, 0, R92C_RF_CHNLBW) | R92C_RF_CHNLBW_LCSTART); 4731 1.1 nonaka 4732 1.1 nonaka /* Give calibration the time to complete. */ 4733 1.49 nat urtwn_delay_ms(sc, 100); 4734 1.1 nonaka 4735 1.1 nonaka /* Restore configuration. */ 4736 1.1 nonaka if ((txmode & 0x70) != 0) { 4737 1.1 nonaka /* Restore Tx mode. */ 4738 1.1 nonaka urtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode); 4739 1.1 nonaka /* Restore RF mode. */ 4740 1.1 nonaka for (i = 0; i < sc->nrxchains; i++) { 4741 1.1 nonaka urtwn_rf_write(sc, i, R92C_RF_AC, rf_ac[i]); 4742 1.1 nonaka } 4743 1.1 nonaka } else { 4744 1.1 nonaka /* Unblock all Tx queues. */ 4745 1.1 nonaka urtwn_write_1(sc, R92C_TXPAUSE, 0x00); 4746 1.1 nonaka } 4747 1.1 nonaka } 4748 1.1 nonaka 4749 1.1 nonaka static void 4750 1.1 nonaka urtwn_temp_calib(struct urtwn_softc *sc) 4751 1.1 nonaka { 4752 1.49 nat int temp, t_meter_reg; 4753 1.1 nonaka 4754 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 4755 1.1 nonaka 4756 1.12 christos KASSERT(mutex_owned(&sc->sc_write_mtx)); 4757 1.12 christos 4758 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_92EU)) 4759 1.49 nat t_meter_reg = R92C_RF_T_METER; 4760 1.49 nat else 4761 1.49 nat t_meter_reg = R92E_RF_T_METER; 4762 1.49 nat 4763 1.1 nonaka if (sc->thcal_state == 0) { 4764 1.1 nonaka /* Start measuring temperature. */ 4765 1.74 gson DPRINTFN(DBG_RF, "start measuring temperature", 0, 0, 0, 0); 4766 1.49 nat urtwn_rf_write(sc, 0, t_meter_reg, 0x60); 4767 1.1 nonaka sc->thcal_state = 1; 4768 1.1 nonaka return; 4769 1.1 nonaka } 4770 1.1 nonaka sc->thcal_state = 0; 4771 1.1 nonaka 4772 1.1 nonaka /* Read measured temperature. */ 4773 1.1 nonaka temp = urtwn_rf_read(sc, 0, R92C_RF_T_METER) & 0x1f; 4774 1.74 gson DPRINTFN(DBG_RF, "temperature=%jd", temp, 0, 0, 0); 4775 1.49 nat if (temp == 0) /* Read failed, skip. */ 4776 1.1 nonaka return; 4777 1.1 nonaka 4778 1.1 nonaka /* 4779 1.1 nonaka * Redo LC calibration if temperature changed significantly since 4780 1.1 nonaka * last calibration. 4781 1.1 nonaka */ 4782 1.1 nonaka if (sc->thcal_lctemp == 0) { 4783 1.1 nonaka /* First LC calibration is performed in urtwn_init(). */ 4784 1.1 nonaka sc->thcal_lctemp = temp; 4785 1.1 nonaka } else if (abs(temp - sc->thcal_lctemp) > 1) { 4786 1.74 gson DPRINTFN(DBG_RF, "LC calib triggered by temp: %jd -> %jd", 4787 1.74 gson sc->thcal_lctemp, temp, 0, 0); 4788 1.1 nonaka urtwn_lc_calib(sc); 4789 1.1 nonaka /* Record temperature of last LC calibration. */ 4790 1.1 nonaka sc->thcal_lctemp = temp; 4791 1.1 nonaka } 4792 1.1 nonaka } 4793 1.1 nonaka 4794 1.1 nonaka static int 4795 1.1 nonaka urtwn_init(struct ifnet *ifp) 4796 1.1 nonaka { 4797 1.1 nonaka struct urtwn_softc *sc = ifp->if_softc; 4798 1.1 nonaka struct ieee80211com *ic = &sc->sc_ic; 4799 1.1 nonaka struct urtwn_rx_data *data; 4800 1.1 nonaka uint32_t reg; 4801 1.22 christos size_t i; 4802 1.22 christos int error; 4803 1.1 nonaka 4804 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 4805 1.1 nonaka 4806 1.1 nonaka urtwn_stop(ifp, 0); 4807 1.1 nonaka 4808 1.12 christos mutex_enter(&sc->sc_write_mtx); 4809 1.12 christos 4810 1.1 nonaka mutex_enter(&sc->sc_task_mtx); 4811 1.1 nonaka /* Init host async commands ring. */ 4812 1.1 nonaka sc->cmdq.cur = sc->cmdq.next = sc->cmdq.queued = 0; 4813 1.1 nonaka mutex_exit(&sc->sc_task_mtx); 4814 1.1 nonaka 4815 1.1 nonaka mutex_enter(&sc->sc_fwcmd_mtx); 4816 1.1 nonaka /* Init firmware commands ring. */ 4817 1.1 nonaka sc->fwcur = 0; 4818 1.1 nonaka mutex_exit(&sc->sc_fwcmd_mtx); 4819 1.1 nonaka 4820 1.12 christos /* Allocate Tx/Rx buffers. */ 4821 1.12 christos error = urtwn_alloc_rx_list(sc); 4822 1.12 christos if (error != 0) { 4823 1.12 christos aprint_error_dev(sc->sc_dev, 4824 1.12 christos "could not allocate Rx buffers\n"); 4825 1.12 christos goto fail; 4826 1.12 christos } 4827 1.12 christos error = urtwn_alloc_tx_list(sc); 4828 1.12 christos if (error != 0) { 4829 1.12 christos aprint_error_dev(sc->sc_dev, 4830 1.12 christos "could not allocate Tx buffers\n"); 4831 1.12 christos goto fail; 4832 1.1 nonaka } 4833 1.1 nonaka 4834 1.1 nonaka /* Power on adapter. */ 4835 1.1 nonaka error = urtwn_power_on(sc); 4836 1.1 nonaka if (error != 0) 4837 1.1 nonaka goto fail; 4838 1.1 nonaka 4839 1.1 nonaka /* Initialize DMA. */ 4840 1.1 nonaka error = urtwn_dma_init(sc); 4841 1.1 nonaka if (error != 0) 4842 1.1 nonaka goto fail; 4843 1.1 nonaka 4844 1.1 nonaka /* Set info size in Rx descriptors (in 64-bit words). */ 4845 1.1 nonaka urtwn_write_1(sc, R92C_RX_DRVINFO_SZ, 4); 4846 1.1 nonaka 4847 1.1 nonaka /* Init interrupts. */ 4848 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_88E) || 4849 1.111 riastrad ISSET(sc->chip, URTWN_CHIP_92EU)) { 4850 1.32 nonaka urtwn_write_4(sc, R88E_HISR, 0xffffffff); 4851 1.32 nonaka urtwn_write_4(sc, R88E_HIMR, R88E_HIMR_CPWM | R88E_HIMR_CPWM2 | 4852 1.32 nonaka R88E_HIMR_TBDER | R88E_HIMR_PSTIMEOUT); 4853 1.32 nonaka urtwn_write_4(sc, R88E_HIMRE, R88E_HIMRE_RXFOVW | 4854 1.32 nonaka R88E_HIMRE_TXFOVW | R88E_HIMRE_RXERR | R88E_HIMRE_TXERR); 4855 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_88E)) { 4856 1.49 nat urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION, 4857 1.49 nat urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) | 4858 1.49 nat R92C_USB_SPECIAL_OPTION_INT_BULK_SEL); 4859 1.49 nat } 4860 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_92EU)) 4861 1.49 nat urtwn_write_1(sc, R92C_USB_HRPWM, 0); 4862 1.32 nonaka } else { 4863 1.32 nonaka urtwn_write_4(sc, R92C_HISR, 0xffffffff); 4864 1.32 nonaka urtwn_write_4(sc, R92C_HIMR, 0xffffffff); 4865 1.32 nonaka } 4866 1.1 nonaka 4867 1.1 nonaka /* Set MAC address. */ 4868 1.1 nonaka IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl)); 4869 1.1 nonaka urtwn_write_region(sc, R92C_MACID, ic->ic_myaddr, IEEE80211_ADDR_LEN); 4870 1.1 nonaka 4871 1.1 nonaka /* Set initial network type. */ 4872 1.1 nonaka reg = urtwn_read_4(sc, R92C_CR); 4873 1.1 nonaka switch (ic->ic_opmode) { 4874 1.1 nonaka case IEEE80211_M_STA: 4875 1.1 nonaka default: 4876 1.1 nonaka reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_INFRA); 4877 1.1 nonaka break; 4878 1.7 christos 4879 1.1 nonaka case IEEE80211_M_IBSS: 4880 1.1 nonaka reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_ADHOC); 4881 1.1 nonaka break; 4882 1.1 nonaka } 4883 1.1 nonaka urtwn_write_4(sc, R92C_CR, reg); 4884 1.1 nonaka 4885 1.1 nonaka /* Set response rate */ 4886 1.1 nonaka reg = urtwn_read_4(sc, R92C_RRSR); 4887 1.1 nonaka reg = RW(reg, R92C_RRSR_RATE_BITMAP, R92C_RRSR_RATE_CCK_ONLY_1M); 4888 1.1 nonaka urtwn_write_4(sc, R92C_RRSR, reg); 4889 1.1 nonaka 4890 1.1 nonaka /* SIFS (used in NAV) */ 4891 1.1 nonaka urtwn_write_2(sc, R92C_SPEC_SIFS, 4892 1.1 nonaka SM(R92C_SPEC_SIFS_CCK, 0x10) | SM(R92C_SPEC_SIFS_OFDM, 0x10)); 4893 1.1 nonaka 4894 1.1 nonaka /* Set short/long retry limits. */ 4895 1.1 nonaka urtwn_write_2(sc, R92C_RL, 4896 1.1 nonaka SM(R92C_RL_SRL, 0x30) | SM(R92C_RL_LRL, 0x30)); 4897 1.1 nonaka 4898 1.1 nonaka /* Initialize EDCA parameters. */ 4899 1.1 nonaka urtwn_edca_init(sc); 4900 1.1 nonaka 4901 1.1 nonaka /* Setup rate fallback. */ 4902 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_88E) && 4903 1.49 nat !ISSET(sc->chip, URTWN_CHIP_92EU)) { 4904 1.32 nonaka urtwn_write_4(sc, R92C_DARFRC + 0, 0x00000000); 4905 1.32 nonaka urtwn_write_4(sc, R92C_DARFRC + 4, 0x10080404); 4906 1.32 nonaka urtwn_write_4(sc, R92C_RARFRC + 0, 0x04030201); 4907 1.32 nonaka urtwn_write_4(sc, R92C_RARFRC + 4, 0x08070605); 4908 1.32 nonaka } 4909 1.1 nonaka 4910 1.1 nonaka urtwn_write_1(sc, R92C_FWHW_TXQ_CTRL, 4911 1.1 nonaka urtwn_read_1(sc, R92C_FWHW_TXQ_CTRL) | 4912 1.1 nonaka R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW); 4913 1.1 nonaka /* Set ACK timeout. */ 4914 1.1 nonaka urtwn_write_1(sc, R92C_ACKTO, 0x40); 4915 1.1 nonaka 4916 1.1 nonaka /* Setup USB aggregation. */ 4917 1.1 nonaka /* Tx */ 4918 1.1 nonaka reg = urtwn_read_4(sc, R92C_TDECTRL); 4919 1.1 nonaka reg = RW(reg, R92C_TDECTRL_BLK_DESC_NUM, 6); 4920 1.1 nonaka urtwn_write_4(sc, R92C_TDECTRL, reg); 4921 1.1 nonaka /* Rx */ 4922 1.1 nonaka urtwn_write_1(sc, R92C_TRXDMA_CTRL, 4923 1.1 nonaka urtwn_read_1(sc, R92C_TRXDMA_CTRL) | 4924 1.1 nonaka R92C_TRXDMA_CTRL_RXDMA_AGG_EN); 4925 1.1 nonaka urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION, 4926 1.1 nonaka urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) & 4927 1.1 nonaka ~R92C_USB_SPECIAL_OPTION_AGG_EN); 4928 1.1 nonaka urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48); 4929 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_88E) || 4930 1.49 nat ISSET(sc->chip, URTWN_CHIP_92EU)) 4931 1.32 nonaka urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH + 1, 4); 4932 1.32 nonaka else 4933 1.32 nonaka urtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4); 4934 1.1 nonaka 4935 1.1 nonaka /* Initialize beacon parameters. */ 4936 1.32 nonaka urtwn_write_2(sc, R92C_BCN_CTRL, 0x1010); 4937 1.1 nonaka urtwn_write_2(sc, R92C_TBTT_PROHIBIT, 0x6404); 4938 1.60 thorpej urtwn_write_1(sc, R92C_DRVERLYINT, R92C_DRVERLYINT_INIT_TIME); 4939 1.60 thorpej urtwn_write_1(sc, R92C_BCNDMATIM, R92C_BCNDMATIM_INIT_TIME); 4940 1.1 nonaka urtwn_write_2(sc, R92C_BCNTCFG, 0x660f); 4941 1.1 nonaka 4942 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_88E) && 4943 1.49 nat !ISSET(sc->chip, URTWN_CHIP_92EU)) { 4944 1.32 nonaka /* Setup AMPDU aggregation. */ 4945 1.32 nonaka urtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631); /* MCS7~0 */ 4946 1.32 nonaka urtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16); 4947 1.32 nonaka urtwn_write_2(sc, 0x4ca, 0x0708); 4948 1.1 nonaka 4949 1.32 nonaka urtwn_write_1(sc, R92C_BCN_MAX_ERR, 0xff); 4950 1.32 nonaka urtwn_write_1(sc, R92C_BCN_CTRL, R92C_BCN_CTRL_DIS_TSF_UDT0); 4951 1.32 nonaka } 4952 1.1 nonaka 4953 1.1 nonaka /* Load 8051 microcode. */ 4954 1.1 nonaka error = urtwn_load_firmware(sc); 4955 1.1 nonaka if (error != 0) 4956 1.1 nonaka goto fail; 4957 1.1 nonaka SET(sc->sc_flags, URTWN_FLAG_FWREADY); 4958 1.1 nonaka 4959 1.1 nonaka /* Initialize MAC/BB/RF blocks. */ 4960 1.19 christos /* 4961 1.19 christos * XXX: urtwn_mac_init() sets R92C_RCR[0:15] = R92C_RCR_APM | 4962 1.19 christos * R92C_RCR_AM | R92C_RCR_AB | R92C_RCR_AICV | R92C_RCR_AMF. 4963 1.19 christos * XXX: This setting should be removed from rtl8192cu_mac[]. 4964 1.19 christos */ 4965 1.19 christos urtwn_mac_init(sc); // sets R92C_RCR[0:15] 4966 1.19 christos urtwn_rxfilter_init(sc); // reset R92C_RCR 4967 1.1 nonaka urtwn_bb_init(sc); 4968 1.1 nonaka urtwn_rf_init(sc); 4969 1.1 nonaka 4970 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_88E) || 4971 1.49 nat ISSET(sc->chip, URTWN_CHIP_92EU)) { 4972 1.32 nonaka urtwn_write_2(sc, R92C_CR, 4973 1.32 nonaka urtwn_read_2(sc, R92C_CR) | R92C_CR_MACTXEN | 4974 1.32 nonaka R92C_CR_MACRXEN); 4975 1.32 nonaka } 4976 1.32 nonaka 4977 1.1 nonaka /* Turn CCK and OFDM blocks on. */ 4978 1.1 nonaka reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD); 4979 1.1 nonaka reg |= R92C_RFMOD_CCK_EN; 4980 1.1 nonaka urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg); 4981 1.1 nonaka reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD); 4982 1.1 nonaka reg |= R92C_RFMOD_OFDM_EN; 4983 1.1 nonaka urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg); 4984 1.1 nonaka 4985 1.1 nonaka /* Clear per-station keys table. */ 4986 1.1 nonaka urtwn_cam_init(sc); 4987 1.1 nonaka 4988 1.1 nonaka /* Enable hardware sequence numbering. */ 4989 1.1 nonaka urtwn_write_1(sc, R92C_HWSEQ_CTRL, 0xff); 4990 1.1 nonaka 4991 1.1 nonaka /* Perform LO and IQ calibrations. */ 4992 1.1 nonaka urtwn_iq_calib(sc, sc->iqk_inited); 4993 1.1 nonaka sc->iqk_inited = true; 4994 1.1 nonaka 4995 1.1 nonaka /* Perform LC calibration. */ 4996 1.1 nonaka urtwn_lc_calib(sc); 4997 1.1 nonaka 4998 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_88E) && 4999 1.49 nat !ISSET(sc->chip, URTWN_CHIP_92EU)) { 5000 1.32 nonaka /* Fix USB interference issue. */ 5001 1.32 nonaka urtwn_write_1(sc, 0xfe40, 0xe0); 5002 1.32 nonaka urtwn_write_1(sc, 0xfe41, 0x8d); 5003 1.32 nonaka urtwn_write_1(sc, 0xfe42, 0x80); 5004 1.32 nonaka urtwn_write_4(sc, 0x20c, 0xfd0320); 5005 1.1 nonaka 5006 1.32 nonaka urtwn_pa_bias_init(sc); 5007 1.32 nonaka } 5008 1.1 nonaka 5009 1.49 nat if (!(sc->chip & (URTWN_CHIP_92C | URTWN_CHIP_92C_1T2R)) || 5010 1.49 nat !(sc->chip & URTWN_CHIP_92EU)) { 5011 1.1 nonaka /* 1T1R */ 5012 1.1 nonaka urtwn_bb_write(sc, R92C_FPGA0_RFPARAM(0), 5013 1.1 nonaka urtwn_bb_read(sc, R92C_FPGA0_RFPARAM(0)) | __BIT(13)); 5014 1.1 nonaka } 5015 1.1 nonaka 5016 1.1 nonaka /* Initialize GPIO setting. */ 5017 1.1 nonaka urtwn_write_1(sc, R92C_GPIO_MUXCFG, 5018 1.1 nonaka urtwn_read_1(sc, R92C_GPIO_MUXCFG) & ~R92C_GPIO_MUXCFG_ENBT); 5019 1.1 nonaka 5020 1.1 nonaka /* Fix for lower temperature. */ 5021 1.49 nat if (!ISSET(sc->chip, URTWN_CHIP_88E) && 5022 1.49 nat !ISSET(sc->chip, URTWN_CHIP_92EU)) 5023 1.32 nonaka urtwn_write_1(sc, 0x15, 0xe9); 5024 1.1 nonaka 5025 1.1 nonaka /* Set default channel. */ 5026 1.13 jmcneill urtwn_set_chan(sc, ic->ic_curchan, IEEE80211_HTINFO_2NDCHAN_NONE); 5027 1.1 nonaka 5028 1.1 nonaka /* Queue Rx xfers. */ 5029 1.49 nat for (size_t j = 0; j < sc->rx_npipe; j++) { 5030 1.49 nat for (i = 0; i < URTWN_RX_LIST_COUNT; i++) { 5031 1.49 nat data = &sc->rx_data[j][i]; 5032 1.49 nat usbd_setup_xfer(data->xfer, data, data->buf, 5033 1.49 nat URTWN_RXBUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, 5034 1.49 nat urtwn_rxeof); 5035 1.49 nat error = usbd_transfer(data->xfer); 5036 1.49 nat if (__predict_false(error != USBD_NORMAL_COMPLETION && 5037 1.49 nat error != USBD_IN_PROGRESS)) 5038 1.49 nat goto fail; 5039 1.49 nat } 5040 1.1 nonaka } 5041 1.1 nonaka 5042 1.1 nonaka /* We're ready to go. */ 5043 1.1 nonaka ifp->if_flags &= ~IFF_OACTIVE; 5044 1.1 nonaka ifp->if_flags |= IFF_RUNNING; 5045 1.49 nat sc->sc_running = true; 5046 1.1 nonaka 5047 1.16 jmcneill mutex_exit(&sc->sc_write_mtx); 5048 1.16 jmcneill 5049 1.1 nonaka if (ic->ic_opmode == IEEE80211_M_MONITOR) 5050 1.1 nonaka ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 5051 1.16 jmcneill else if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) 5052 1.1 nonaka ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 5053 1.16 jmcneill urtwn_wait_async(sc); 5054 1.12 christos 5055 1.42 skrll return 0; 5056 1.1 nonaka 5057 1.1 nonaka fail: 5058 1.12 christos mutex_exit(&sc->sc_write_mtx); 5059 1.12 christos 5060 1.1 nonaka urtwn_stop(ifp, 1); 5061 1.42 skrll return error; 5062 1.1 nonaka } 5063 1.1 nonaka 5064 1.88 jdolecek static void __noinline 5065 1.1 nonaka urtwn_stop(struct ifnet *ifp, int disable) 5066 1.1 nonaka { 5067 1.1 nonaka struct urtwn_softc *sc = ifp->if_softc; 5068 1.1 nonaka struct ieee80211com *ic = &sc->sc_ic; 5069 1.22 christos size_t i; 5070 1.22 christos int s; 5071 1.1 nonaka 5072 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 5073 1.1 nonaka 5074 1.1 nonaka s = splusb(); 5075 1.1 nonaka ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 5076 1.1 nonaka urtwn_wait_async(sc); 5077 1.1 nonaka splx(s); 5078 1.1 nonaka 5079 1.16 jmcneill sc->tx_timer = 0; 5080 1.16 jmcneill ifp->if_timer = 0; 5081 1.16 jmcneill ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 5082 1.16 jmcneill 5083 1.1 nonaka callout_stop(&sc->sc_scan_to); 5084 1.1 nonaka callout_stop(&sc->sc_calib_to); 5085 1.1 nonaka 5086 1.1 nonaka /* Abort Tx. */ 5087 1.49 nat for (i = 0; i < sc->tx_npipe; i++) { 5088 1.1 nonaka if (sc->tx_pipe[i] != NULL) 5089 1.1 nonaka usbd_abort_pipe(sc->tx_pipe[i]); 5090 1.1 nonaka } 5091 1.1 nonaka 5092 1.1 nonaka /* Stop Rx pipe. */ 5093 1.49 nat for (i = 0; i < sc->rx_npipe; i++) { 5094 1.49 nat if (sc->rx_pipe[i] != NULL) 5095 1.49 nat usbd_abort_pipe(sc->rx_pipe[i]); 5096 1.49 nat } 5097 1.1 nonaka 5098 1.12 christos /* Free Tx/Rx buffers. */ 5099 1.12 christos urtwn_free_tx_list(sc); 5100 1.12 christos urtwn_free_rx_list(sc); 5101 1.12 christos 5102 1.49 nat sc->sc_running = false; 5103 1.1 nonaka if (disable) 5104 1.1 nonaka urtwn_chip_stop(sc); 5105 1.1 nonaka } 5106 1.1 nonaka 5107 1.16 jmcneill static int 5108 1.16 jmcneill urtwn_reset(struct ifnet *ifp) 5109 1.16 jmcneill { 5110 1.16 jmcneill struct urtwn_softc *sc = ifp->if_softc; 5111 1.16 jmcneill struct ieee80211com *ic = &sc->sc_ic; 5112 1.16 jmcneill 5113 1.16 jmcneill if (ic->ic_opmode != IEEE80211_M_MONITOR) 5114 1.16 jmcneill return ENETRESET; 5115 1.16 jmcneill 5116 1.16 jmcneill urtwn_set_chan(sc, ic->ic_curchan, IEEE80211_HTINFO_2NDCHAN_NONE); 5117 1.16 jmcneill 5118 1.16 jmcneill return 0; 5119 1.16 jmcneill } 5120 1.16 jmcneill 5121 1.1 nonaka static void 5122 1.1 nonaka urtwn_chip_stop(struct urtwn_softc *sc) 5123 1.1 nonaka { 5124 1.1 nonaka uint32_t reg; 5125 1.1 nonaka bool disabled = true; 5126 1.1 nonaka 5127 1.74 gson URTWNHIST_FUNC(); URTWNHIST_CALLED(); 5128 1.1 nonaka 5129 1.62 jmcneill if (ISSET(sc->chip, URTWN_CHIP_88E) || 5130 1.62 jmcneill ISSET(sc->chip, URTWN_CHIP_92EU)) 5131 1.49 nat return; 5132 1.49 nat 5133 1.12 christos mutex_enter(&sc->sc_write_mtx); 5134 1.12 christos 5135 1.1 nonaka /* 5136 1.1 nonaka * RF Off Sequence 5137 1.1 nonaka */ 5138 1.1 nonaka /* Pause MAC TX queue */ 5139 1.1 nonaka urtwn_write_1(sc, R92C_TXPAUSE, 0xFF); 5140 1.1 nonaka 5141 1.1 nonaka /* Disable RF */ 5142 1.1 nonaka urtwn_rf_write(sc, 0, 0, 0); 5143 1.1 nonaka 5144 1.1 nonaka urtwn_write_1(sc, R92C_APSD_CTRL, R92C_APSD_CTRL_OFF); 5145 1.1 nonaka 5146 1.1 nonaka /* Reset BB state machine */ 5147 1.1 nonaka urtwn_write_1(sc, R92C_SYS_FUNC_EN, 5148 1.1 nonaka R92C_SYS_FUNC_EN_USBD | 5149 1.1 nonaka R92C_SYS_FUNC_EN_USBA | 5150 1.1 nonaka R92C_SYS_FUNC_EN_BB_GLB_RST); 5151 1.1 nonaka urtwn_write_1(sc, R92C_SYS_FUNC_EN, 5152 1.1 nonaka R92C_SYS_FUNC_EN_USBD | R92C_SYS_FUNC_EN_USBA); 5153 1.1 nonaka 5154 1.1 nonaka /* 5155 1.1 nonaka * Reset digital sequence 5156 1.1 nonaka */ 5157 1.1 nonaka if (urtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY) { 5158 1.1 nonaka /* Reset MCU ready status */ 5159 1.1 nonaka urtwn_write_1(sc, R92C_MCUFWDL, 0); 5160 1.1 nonaka /* If firmware in ram code, do reset */ 5161 1.1 nonaka if (ISSET(sc->sc_flags, URTWN_FLAG_FWREADY)) { 5162 1.49 nat if (ISSET(sc->chip, URTWN_CHIP_88E) || 5163 1.49 nat ISSET(sc->chip, URTWN_CHIP_92EU)) 5164 1.32 nonaka urtwn_r88e_fw_reset(sc); 5165 1.32 nonaka else 5166 1.32 nonaka urtwn_fw_reset(sc); 5167 1.1 nonaka CLR(sc->sc_flags, URTWN_FLAG_FWREADY); 5168 1.1 nonaka } 5169 1.1 nonaka } 5170 1.1 nonaka 5171 1.1 nonaka /* Reset MAC and Enable 8051 */ 5172 1.1 nonaka urtwn_write_1(sc, R92C_SYS_FUNC_EN + 1, 0x54); 5173 1.1 nonaka 5174 1.1 nonaka /* Reset MCU ready status */ 5175 1.1 nonaka urtwn_write_1(sc, R92C_MCUFWDL, 0); 5176 1.1 nonaka 5177 1.1 nonaka if (disabled) { 5178 1.1 nonaka /* Disable MAC clock */ 5179 1.1 nonaka urtwn_write_2(sc, R92C_SYS_CLKR, 0x70A3); 5180 1.1 nonaka /* Disable AFE PLL */ 5181 1.1 nonaka urtwn_write_1(sc, R92C_AFE_PLL_CTRL, 0x80); 5182 1.1 nonaka /* Gated AFE DIG_CLOCK */ 5183 1.1 nonaka urtwn_write_2(sc, R92C_AFE_XTAL_CTRL, 0x880F); 5184 1.1 nonaka /* Isolated digital to PON */ 5185 1.1 nonaka urtwn_write_1(sc, R92C_SYS_ISO_CTRL, 0xF9); 5186 1.1 nonaka } 5187 1.1 nonaka 5188 1.1 nonaka /* 5189 1.1 nonaka * Pull GPIO PIN to balance level and LED control 5190 1.1 nonaka */ 5191 1.1 nonaka /* 1. Disable GPIO[7:0] */ 5192 1.1 nonaka urtwn_write_2(sc, R92C_GPIO_PIN_CTRL + 2, 0x0000); 5193 1.1 nonaka 5194 1.1 nonaka reg = urtwn_read_4(sc, R92C_GPIO_PIN_CTRL) & ~0x0000ff00; 5195 1.1 nonaka reg |= ((reg << 8) & 0x0000ff00) | 0x00ff0000; 5196 1.1 nonaka urtwn_write_4(sc, R92C_GPIO_PIN_CTRL, reg); 5197 1.1 nonaka 5198 1.28 christos /* Disable GPIO[10:8] */ 5199 1.28 christos urtwn_write_1(sc, R92C_GPIO_MUXCFG + 3, 0x00); 5200 1.1 nonaka 5201 1.1 nonaka reg = urtwn_read_2(sc, R92C_GPIO_MUXCFG + 2) & ~0x00f0; 5202 1.28 christos reg |= (((reg & 0x000f) << 4) | 0x0780); 5203 1.41 nonaka urtwn_write_2(sc, R92C_GPIO_MUXCFG + 2, reg); 5204 1.1 nonaka 5205 1.1 nonaka /* Disable LED0 & 1 */ 5206 1.28 christos urtwn_write_2(sc, R92C_LEDCFG0, 0x8080); 5207 1.1 nonaka 5208 1.1 nonaka /* 5209 1.1 nonaka * Reset digital sequence 5210 1.1 nonaka */ 5211 1.28 christos if (disabled) { 5212 1.1 nonaka /* Disable ELDR clock */ 5213 1.1 nonaka urtwn_write_2(sc, R92C_SYS_CLKR, 0x70A3); 5214 1.1 nonaka /* Isolated ELDR to PON */ 5215 1.1 nonaka urtwn_write_1(sc, R92C_SYS_ISO_CTRL + 1, 0x82); 5216 1.1 nonaka } 5217 1.1 nonaka 5218 1.1 nonaka /* 5219 1.1 nonaka * Disable analog sequence 5220 1.1 nonaka */ 5221 1.28 christos if (disabled) { 5222 1.1 nonaka /* Disable A15 power */ 5223 1.28 christos urtwn_write_1(sc, R92C_LDOA15_CTRL, 0x04); 5224 1.1 nonaka /* Disable digital core power */ 5225 1.28 christos urtwn_write_1(sc, R92C_LDOV12D_CTRL, 5226 1.28 christos urtwn_read_1(sc, R92C_LDOV12D_CTRL) & 5227 1.1 nonaka ~R92C_LDOV12D_CTRL_LDV12_EN); 5228 1.28 christos } 5229 1.1 nonaka 5230 1.1 nonaka /* Enter PFM mode */ 5231 1.1 nonaka urtwn_write_1(sc, R92C_SPS0_CTRL, 0x23); 5232 1.1 nonaka 5233 1.1 nonaka /* Set USB suspend */ 5234 1.1 nonaka urtwn_write_2(sc, R92C_APS_FSMCO, 5235 1.1 nonaka R92C_APS_FSMCO_APDM_HOST | 5236 1.1 nonaka R92C_APS_FSMCO_AFSM_HSUS | 5237 1.1 nonaka R92C_APS_FSMCO_PFM_ALDN); 5238 1.1 nonaka 5239 1.1 nonaka urtwn_write_1(sc, R92C_RSV_CTRL, 0x0E); 5240 1.12 christos 5241 1.12 christos mutex_exit(&sc->sc_write_mtx); 5242 1.1 nonaka } 5243 1.1 nonaka 5244 1.49 nat static void 5245 1.49 nat urtwn_delay_ms(struct urtwn_softc *sc, int ms) 5246 1.49 nat { 5247 1.49 nat if (sc->sc_running == false) 5248 1.49 nat DELAY(ms * 1000); 5249 1.49 nat else 5250 1.49 nat usbd_delay_ms(sc->sc_udev, ms); 5251 1.49 nat } 5252 1.49 nat 5253 1.64 christos MODULE(MODULE_CLASS_DRIVER, if_urtwn, NULL); 5254 1.1 nonaka 5255 1.1 nonaka #ifdef _MODULE 5256 1.1 nonaka #include "ioconf.c" 5257 1.1 nonaka #endif 5258 1.1 nonaka 5259 1.1 nonaka static int 5260 1.1 nonaka if_urtwn_modcmd(modcmd_t cmd, void *aux) 5261 1.1 nonaka { 5262 1.1 nonaka int error = 0; 5263 1.1 nonaka 5264 1.1 nonaka switch (cmd) { 5265 1.1 nonaka case MODULE_CMD_INIT: 5266 1.1 nonaka #ifdef _MODULE 5267 1.1 nonaka error = config_init_component(cfdriver_ioconf_urtwn, 5268 1.1 nonaka cfattach_ioconf_urtwn, cfdata_ioconf_urtwn); 5269 1.1 nonaka #endif 5270 1.42 skrll return error; 5271 1.1 nonaka case MODULE_CMD_FINI: 5272 1.1 nonaka #ifdef _MODULE 5273 1.1 nonaka error = config_fini_component(cfdriver_ioconf_urtwn, 5274 1.1 nonaka cfattach_ioconf_urtwn, cfdata_ioconf_urtwn); 5275 1.1 nonaka #endif 5276 1.42 skrll return error; 5277 1.1 nonaka default: 5278 1.42 skrll return ENOTTY; 5279 1.1 nonaka } 5280 1.1 nonaka } 5281