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