if_urtwn.c revision 263153
1203288Srnoland/* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */ 2203288Srnoland 3203288Srnoland/*- 4203288Srnoland * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> 5203288Srnoland * 6203288Srnoland * Permission to use, copy, modify, and distribute this software for any 7203288Srnoland * purpose with or without fee is hereby granted, provided that the above 8203288Srnoland * copyright notice and this permission notice appear in all copies. 9203288Srnoland * 10203288Srnoland * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11203288Srnoland * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12203288Srnoland * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13203288Srnoland * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14203288Srnoland * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15203288Srnoland * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16203288Srnoland * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17203288Srnoland */ 18203288Srnoland 19203288Srnoland#include <sys/cdefs.h> 20203288Srnoland__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_urtwn.c 263153 2014-03-14 06:37:08Z kevlo $"); 21203288Srnoland 22203288Srnoland/* 23203288Srnoland * Driver for Realtek RTL8188CE-VAU/RTL8188CUS/RTL8188RU/RTL8192CU. 24203288Srnoland */ 25203288Srnoland 26203288Srnoland#include <sys/param.h> 27203288Srnoland#include <sys/sockio.h> 28203288Srnoland#include <sys/sysctl.h> 29203288Srnoland#include <sys/lock.h> 30203288Srnoland#include <sys/mutex.h> 31203288Srnoland#include <sys/mbuf.h> 32203288Srnoland#include <sys/kernel.h> 33203288Srnoland#include <sys/socket.h> 34203288Srnoland#include <sys/systm.h> 35203288Srnoland#include <sys/malloc.h> 36203288Srnoland#include <sys/module.h> 37203288Srnoland#include <sys/bus.h> 38203288Srnoland#include <sys/endian.h> 39203288Srnoland#include <sys/linker.h> 40203288Srnoland#include <sys/firmware.h> 41203288Srnoland#include <sys/kdb.h> 42203288Srnoland 43203288Srnoland#include <machine/bus.h> 44203288Srnoland#include <machine/resource.h> 45203288Srnoland#include <sys/rman.h> 46203288Srnoland 47203288Srnoland#include <net/bpf.h> 48203288Srnoland#include <net/if.h> 49203288Srnoland#include <net/if_var.h> 50203288Srnoland#include <net/if_arp.h> 51203288Srnoland#include <net/ethernet.h> 52203288Srnoland#include <net/if_dl.h> 53203288Srnoland#include <net/if_media.h> 54203288Srnoland#include <net/if_types.h> 55203288Srnoland 56203288Srnoland#include <netinet/in.h> 57203288Srnoland#include <netinet/in_systm.h> 58203288Srnoland#include <netinet/in_var.h> 59203288Srnoland#include <netinet/if_ether.h> 60203288Srnoland#include <netinet/ip.h> 61203288Srnoland 62203288Srnoland#include <net80211/ieee80211_var.h> 63203288Srnoland#include <net80211/ieee80211_regdomain.h> 64203288Srnoland#include <net80211/ieee80211_radiotap.h> 65203288Srnoland#include <net80211/ieee80211_ratectl.h> 66203288Srnoland 67203288Srnoland#include <dev/usb/usb.h> 68203288Srnoland#include <dev/usb/usbdi.h> 69203288Srnoland#include "usbdevs.h" 70203288Srnoland 71203288Srnoland#define USB_DEBUG_VAR urtwn_debug 72203288Srnoland#include <dev/usb/usb_debug.h> 73203288Srnoland 74203288Srnoland#include <dev/usb/wlan/if_urtwnreg.h> 75203288Srnoland 76203288Srnoland#ifdef USB_DEBUG 77203288Srnolandstatic int urtwn_debug = 0; 78203288Srnoland 79203288SrnolandSYSCTL_NODE(_hw_usb, OID_AUTO, urtwn, CTLFLAG_RW, 0, "USB urtwn"); 80203288SrnolandSYSCTL_INT(_hw_usb_urtwn, OID_AUTO, debug, CTLFLAG_RW, &urtwn_debug, 0, 81203288Srnoland "Debug level"); 82203288Srnoland#endif 83203288Srnoland 84203288Srnoland#define URTWN_RSSI(r) (r) - 110 85203288Srnoland#define IEEE80211_HAS_ADDR4(wh) \ 86203288Srnoland (((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) 87203288Srnoland 88203288Srnoland/* various supported device vendors/products */ 89203288Srnolandstatic const STRUCT_USB_HOST_ID urtwn_devs[] = { 90203288Srnoland#define URTWN_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } 91203288Srnoland URTWN_DEV(ABOCOM, RTL8188CU_1), 92203288Srnoland URTWN_DEV(ABOCOM, RTL8188CU_2), 93203288Srnoland URTWN_DEV(ABOCOM, RTL8192CU), 94203288Srnoland URTWN_DEV(ASUS, RTL8192CU), 95203288Srnoland URTWN_DEV(AZUREWAVE, RTL8188CE_1), 96203288Srnoland URTWN_DEV(AZUREWAVE, RTL8188CE_2), 97203288Srnoland URTWN_DEV(AZUREWAVE, RTL8188CU), 98203288Srnoland URTWN_DEV(BELKIN, F7D2102), 99203288Srnoland URTWN_DEV(BELKIN, RTL8188CU), 100203288Srnoland URTWN_DEV(BELKIN, RTL8192CU), 101203288Srnoland URTWN_DEV(CHICONY, RTL8188CUS_1), 102203288Srnoland URTWN_DEV(CHICONY, RTL8188CUS_2), 103203288Srnoland URTWN_DEV(CHICONY, RTL8188CUS_3), 104203288Srnoland URTWN_DEV(CHICONY, RTL8188CUS_4), 105203288Srnoland URTWN_DEV(CHICONY, RTL8188CUS_5), 106203288Srnoland URTWN_DEV(COREGA, RTL8192CU), 107203288Srnoland URTWN_DEV(DLINK, RTL8188CU), 108203288Srnoland URTWN_DEV(DLINK, RTL8192CU_1), 109203288Srnoland URTWN_DEV(DLINK, RTL8192CU_2), 110203288Srnoland URTWN_DEV(DLINK, RTL8192CU_3), 111203288Srnoland URTWN_DEV(DLINK, DWA131B), 112203288Srnoland URTWN_DEV(EDIMAX, EW7811UN), 113203288Srnoland URTWN_DEV(EDIMAX, RTL8192CU), 114203288Srnoland URTWN_DEV(FEIXUN, RTL8188CU), 115203288Srnoland URTWN_DEV(FEIXUN, RTL8192CU), 116203288Srnoland URTWN_DEV(GUILLEMOT, HWNUP150), 117203288Srnoland URTWN_DEV(HAWKING, RTL8192CU), 118203288Srnoland URTWN_DEV(HP3, RTL8188CU), 119203288Srnoland URTWN_DEV(NETGEAR, WNA1000M), 120203288Srnoland URTWN_DEV(NETGEAR, RTL8192CU), 121203288Srnoland URTWN_DEV(NETGEAR4, RTL8188CU), 122203288Srnoland URTWN_DEV(NOVATECH, RTL8188CU), 123203288Srnoland URTWN_DEV(PLANEX2, RTL8188CU_1), 124203288Srnoland URTWN_DEV(PLANEX2, RTL8188CU_2), 125203288Srnoland URTWN_DEV(PLANEX2, RTL8188CU_3), 126203288Srnoland URTWN_DEV(PLANEX2, RTL8188CU_4), 127203288Srnoland URTWN_DEV(PLANEX2, RTL8188CUS), 128203288Srnoland URTWN_DEV(PLANEX2, RTL8192CU), 129203288Srnoland URTWN_DEV(REALTEK, RTL8188CE_0), 130203288Srnoland URTWN_DEV(REALTEK, RTL8188CE_1), 131203288Srnoland URTWN_DEV(REALTEK, RTL8188CTV), 132203288Srnoland URTWN_DEV(REALTEK, RTL8188CU_0), 133203288Srnoland URTWN_DEV(REALTEK, RTL8188CU_1), 134203288Srnoland URTWN_DEV(REALTEK, RTL8188CU_2), 135203288Srnoland URTWN_DEV(REALTEK, RTL8188CU_COMBO), 136203288Srnoland URTWN_DEV(REALTEK, RTL8188CUS), 137203288Srnoland URTWN_DEV(REALTEK, RTL8188RU_1), 138203288Srnoland URTWN_DEV(REALTEK, RTL8188RU_2), 139203288Srnoland URTWN_DEV(REALTEK, RTL8191CU), 140203288Srnoland URTWN_DEV(REALTEK, RTL8192CE), 141203288Srnoland URTWN_DEV(REALTEK, RTL8192CU), 142203288Srnoland URTWN_DEV(REALTEK, RTL8188CU_0), 143203288Srnoland URTWN_DEV(SITECOMEU, RTL8188CU_1), 144203288Srnoland URTWN_DEV(SITECOMEU, RTL8188CU_2), 145203288Srnoland URTWN_DEV(SITECOMEU, RTL8192CU), 146203288Srnoland URTWN_DEV(TRENDNET, RTL8188CU), 147203288Srnoland URTWN_DEV(TRENDNET, RTL8192CU), 148203288Srnoland URTWN_DEV(ZYXEL, RTL8192CU), 149203288Srnoland#undef URTWN_DEV 150203288Srnoland}; 151203288Srnoland 152203288Srnolandstatic device_probe_t urtwn_match; 153203288Srnolandstatic device_attach_t urtwn_attach; 154203288Srnolandstatic device_detach_t urtwn_detach; 155203288Srnoland 156203288Srnolandstatic usb_callback_t urtwn_bulk_tx_callback; 157203288Srnolandstatic usb_callback_t urtwn_bulk_rx_callback; 158203288Srnoland 159203288Srnolandstatic usb_error_t urtwn_do_request(struct urtwn_softc *sc, 160203288Srnoland struct usb_device_request *req, void *data); 161203288Srnolandstatic struct ieee80211vap *urtwn_vap_create(struct ieee80211com *, 162203288Srnoland const char [IFNAMSIZ], int, enum ieee80211_opmode, int, 163203288Srnoland const uint8_t [IEEE80211_ADDR_LEN], 164203288Srnoland const uint8_t [IEEE80211_ADDR_LEN]); 165203288Srnolandstatic void urtwn_vap_delete(struct ieee80211vap *); 166203288Srnolandstatic struct mbuf * urtwn_rx_frame(struct urtwn_softc *, uint8_t *, int, 167203288Srnoland int *); 168203288Srnolandstatic struct mbuf * urtwn_rxeof(struct usb_xfer *, struct urtwn_data *, 169203288Srnoland int *, int8_t *); 170203288Srnolandstatic void urtwn_txeof(struct usb_xfer *, struct urtwn_data *); 171203288Srnolandstatic int urtwn_alloc_list(struct urtwn_softc *, 172203288Srnoland struct urtwn_data[], int, int); 173203288Srnolandstatic int urtwn_alloc_rx_list(struct urtwn_softc *); 174203288Srnolandstatic int urtwn_alloc_tx_list(struct urtwn_softc *); 175203288Srnolandstatic void urtwn_free_tx_list(struct urtwn_softc *); 176203288Srnolandstatic void urtwn_free_rx_list(struct urtwn_softc *); 177203288Srnolandstatic void urtwn_free_list(struct urtwn_softc *, 178203288Srnoland struct urtwn_data data[], int); 179203288Srnolandstatic struct urtwn_data * _urtwn_getbuf(struct urtwn_softc *); 180203288Srnolandstatic struct urtwn_data * urtwn_getbuf(struct urtwn_softc *); 181203288Srnolandstatic int urtwn_write_region_1(struct urtwn_softc *, uint16_t, 182203288Srnoland uint8_t *, int); 183203288Srnolandstatic void urtwn_write_1(struct urtwn_softc *, uint16_t, uint8_t); 184203288Srnolandstatic void urtwn_write_2(struct urtwn_softc *, uint16_t, uint16_t); 185203288Srnolandstatic void urtwn_write_4(struct urtwn_softc *, uint16_t, uint32_t); 186203288Srnolandstatic int urtwn_read_region_1(struct urtwn_softc *, uint16_t, 187203288Srnoland uint8_t *, int); 188203288Srnolandstatic uint8_t urtwn_read_1(struct urtwn_softc *, uint16_t); 189203288Srnolandstatic uint16_t urtwn_read_2(struct urtwn_softc *, uint16_t); 190203288Srnolandstatic uint32_t urtwn_read_4(struct urtwn_softc *, uint16_t); 191203288Srnolandstatic int urtwn_fw_cmd(struct urtwn_softc *, uint8_t, 192203288Srnoland const void *, int); 193203288Srnolandstatic void urtwn_rf_write(struct urtwn_softc *, int, uint8_t, 194203288Srnoland uint32_t); 195203288Srnolandstatic uint32_t urtwn_rf_read(struct urtwn_softc *, int, uint8_t); 196203288Srnolandstatic int urtwn_llt_write(struct urtwn_softc *, uint32_t, 197203288Srnoland uint32_t); 198203288Srnolandstatic uint8_t urtwn_efuse_read_1(struct urtwn_softc *, uint16_t); 199203288Srnolandstatic void urtwn_efuse_read(struct urtwn_softc *); 200203288Srnolandstatic int urtwn_read_chipid(struct urtwn_softc *); 201203288Srnolandstatic void urtwn_read_rom(struct urtwn_softc *); 202203288Srnolandstatic int urtwn_ra_init(struct urtwn_softc *); 203203288Srnolandstatic void urtwn_tsf_sync_enable(struct urtwn_softc *); 204203288Srnolandstatic void urtwn_set_led(struct urtwn_softc *, int, int); 205203288Srnolandstatic int urtwn_newstate(struct ieee80211vap *, 206203288Srnoland enum ieee80211_state, int); 207203288Srnolandstatic void urtwn_watchdog(void *); 208203288Srnolandstatic void urtwn_update_avgrssi(struct urtwn_softc *, int, int8_t); 209203288Srnolandstatic int8_t urtwn_get_rssi(struct urtwn_softc *, int, void *); 210203288Srnolandstatic int urtwn_tx_start(struct urtwn_softc *, 211203288Srnoland struct ieee80211_node *, struct mbuf *, 212203288Srnoland struct urtwn_data *); 213203288Srnolandstatic void urtwn_start(struct ifnet *); 214203288Srnolandstatic void urtwn_start_locked(struct ifnet *, 215203288Srnoland struct urtwn_softc *); 216203288Srnolandstatic int urtwn_ioctl(struct ifnet *, u_long, caddr_t); 217203288Srnolandstatic int urtwn_power_on(struct urtwn_softc *); 218203288Srnolandstatic int urtwn_llt_init(struct urtwn_softc *); 219203288Srnolandstatic void urtwn_fw_reset(struct urtwn_softc *); 220203288Srnolandstatic int urtwn_fw_loadpage(struct urtwn_softc *, int, 221203288Srnoland const uint8_t *, int); 222203288Srnolandstatic int urtwn_load_firmware(struct urtwn_softc *); 223203288Srnolandstatic int urtwn_dma_init(struct urtwn_softc *); 224203288Srnolandstatic void urtwn_mac_init(struct urtwn_softc *); 225203288Srnolandstatic void urtwn_bb_init(struct urtwn_softc *); 226203288Srnolandstatic void urtwn_rf_init(struct urtwn_softc *); 227203288Srnolandstatic void urtwn_cam_init(struct urtwn_softc *); 228203288Srnolandstatic void urtwn_pa_bias_init(struct urtwn_softc *); 229203288Srnolandstatic void urtwn_rxfilter_init(struct urtwn_softc *); 230203288Srnolandstatic void urtwn_edca_init(struct urtwn_softc *); 231203288Srnolandstatic void urtwn_write_txpower(struct urtwn_softc *, int, 232203288Srnoland uint16_t[]); 233203288Srnolandstatic void urtwn_get_txpower(struct urtwn_softc *, int, 234203288Srnoland struct ieee80211_channel *, 235203288Srnoland struct ieee80211_channel *, uint16_t[]); 236203288Srnolandstatic void urtwn_set_txpower(struct urtwn_softc *, 237203288Srnoland struct ieee80211_channel *, 238203288Srnoland struct ieee80211_channel *); 239203288Srnolandstatic void urtwn_scan_start(struct ieee80211com *); 240203288Srnolandstatic void urtwn_scan_end(struct ieee80211com *); 241203288Srnolandstatic void urtwn_set_channel(struct ieee80211com *); 242203288Srnolandstatic void urtwn_set_chan(struct urtwn_softc *, 243203288Srnoland struct ieee80211_channel *, 244203288Srnoland struct ieee80211_channel *); 245203288Srnolandstatic void urtwn_update_mcast(struct ifnet *); 246203288Srnolandstatic void urtwn_iq_calib(struct urtwn_softc *); 247203288Srnolandstatic void urtwn_lc_calib(struct urtwn_softc *); 248203288Srnolandstatic void urtwn_init(void *); 249203288Srnolandstatic void urtwn_init_locked(void *); 250203288Srnolandstatic void urtwn_stop(struct ifnet *); 251203288Srnolandstatic void urtwn_stop_locked(struct ifnet *); 252203288Srnolandstatic void urtwn_abort_xfers(struct urtwn_softc *); 253203288Srnolandstatic int urtwn_raw_xmit(struct ieee80211_node *, struct mbuf *, 254203288Srnoland const struct ieee80211_bpf_params *); 255203288Srnoland 256203288Srnoland/* Aliases. */ 257203288Srnoland#define urtwn_bb_write urtwn_write_4 258203288Srnoland#define urtwn_bb_read urtwn_read_4 259203288Srnoland 260203288Srnolandstatic const struct usb_config urtwn_config[URTWN_N_TRANSFER] = { 261203288Srnoland [URTWN_BULK_RX] = { 262203288Srnoland .type = UE_BULK, 263203288Srnoland .endpoint = UE_ADDR_ANY, 264203288Srnoland .direction = UE_DIR_IN, 265203288Srnoland .bufsize = URTWN_RXBUFSZ, 266203288Srnoland .flags = { 267203288Srnoland .pipe_bof = 1, 268203288Srnoland .short_xfer_ok = 1 269203288Srnoland }, 270203288Srnoland .callback = urtwn_bulk_rx_callback, 271203288Srnoland }, 272203288Srnoland [URTWN_BULK_TX_BE] = { 273203288Srnoland .type = UE_BULK, 274203288Srnoland .endpoint = 0x03, 275203288Srnoland .direction = UE_DIR_OUT, 276203288Srnoland .bufsize = URTWN_TXBUFSZ, 277203288Srnoland .flags = { 278203288Srnoland .ext_buffer = 1, 279203288Srnoland .pipe_bof = 1, 280203288Srnoland .force_short_xfer = 1 281203288Srnoland }, 282203288Srnoland .callback = urtwn_bulk_tx_callback, 283203288Srnoland .timeout = URTWN_TX_TIMEOUT, /* ms */ 284203288Srnoland }, 285203288Srnoland [URTWN_BULK_TX_BK] = { 286203288Srnoland .type = UE_BULK, 287203288Srnoland .endpoint = 0x03, 288203288Srnoland .direction = UE_DIR_OUT, 289203288Srnoland .bufsize = URTWN_TXBUFSZ, 290203288Srnoland .flags = { 291203288Srnoland .ext_buffer = 1, 292203288Srnoland .pipe_bof = 1, 293203288Srnoland .force_short_xfer = 1, 294203288Srnoland }, 295203288Srnoland .callback = urtwn_bulk_tx_callback, 296203288Srnoland .timeout = URTWN_TX_TIMEOUT, /* ms */ 297203288Srnoland }, 298203288Srnoland [URTWN_BULK_TX_VI] = { 299203288Srnoland .type = UE_BULK, 300203288Srnoland .endpoint = 0x02, 301203288Srnoland .direction = UE_DIR_OUT, 302203288Srnoland .bufsize = URTWN_TXBUFSZ, 303203288Srnoland .flags = { 304203288Srnoland .ext_buffer = 1, 305203288Srnoland .pipe_bof = 1, 306203288Srnoland .force_short_xfer = 1 307203288Srnoland }, 308203288Srnoland .callback = urtwn_bulk_tx_callback, 309203288Srnoland .timeout = URTWN_TX_TIMEOUT, /* ms */ 310203288Srnoland }, 311203288Srnoland [URTWN_BULK_TX_VO] = { 312203288Srnoland .type = UE_BULK, 313203288Srnoland .endpoint = 0x02, 314203288Srnoland .direction = UE_DIR_OUT, 315203288Srnoland .bufsize = URTWN_TXBUFSZ, 316203288Srnoland .flags = { 317203288Srnoland .ext_buffer = 1, 318203288Srnoland .pipe_bof = 1, 319203288Srnoland .force_short_xfer = 1 320203288Srnoland }, 321203288Srnoland .callback = urtwn_bulk_tx_callback, 322203288Srnoland .timeout = URTWN_TX_TIMEOUT, /* ms */ 323203288Srnoland }, 324203288Srnoland}; 325203288Srnoland 326203288Srnolandstatic int 327203288Srnolandurtwn_match(device_t self) 328203288Srnoland{ 329203288Srnoland struct usb_attach_arg *uaa = device_get_ivars(self); 330203288Srnoland 331203288Srnoland if (uaa->usb_mode != USB_MODE_HOST) 332203288Srnoland return (ENXIO); 333203288Srnoland if (uaa->info.bConfigIndex != URTWN_CONFIG_INDEX) 334203288Srnoland return (ENXIO); 335203288Srnoland if (uaa->info.bIfaceIndex != URTWN_IFACE_INDEX) 336203288Srnoland return (ENXIO); 337203288Srnoland 338203288Srnoland return (usbd_lookup_id_by_uaa(urtwn_devs, sizeof(urtwn_devs), uaa)); 339203288Srnoland} 340203288Srnoland 341203288Srnolandstatic int 342203288Srnolandurtwn_attach(device_t self) 343203288Srnoland{ 344203288Srnoland struct usb_attach_arg *uaa = device_get_ivars(self); 345203288Srnoland struct urtwn_softc *sc = device_get_softc(self); 346203288Srnoland struct ifnet *ifp; 347203288Srnoland struct ieee80211com *ic; 348203288Srnoland uint8_t iface_index, bands; 349203288Srnoland int error; 350203288Srnoland 351203288Srnoland device_set_usb_desc(self); 352203288Srnoland sc->sc_udev = uaa->device; 353203288Srnoland sc->sc_dev = self; 354203288Srnoland 355203288Srnoland mtx_init(&sc->sc_mtx, device_get_nameunit(self), 356203288Srnoland MTX_NETWORK_LOCK, MTX_DEF); 357203288Srnoland callout_init(&sc->sc_watchdog_ch, 0); 358203288Srnoland 359203288Srnoland iface_index = URTWN_IFACE_INDEX; 360203288Srnoland error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, 361203288Srnoland urtwn_config, URTWN_N_TRANSFER, sc, &sc->sc_mtx); 362203288Srnoland if (error) { 363203288Srnoland device_printf(self, "could not allocate USB transfers, " 364203288Srnoland "err=%s\n", usbd_errstr(error)); 365203288Srnoland goto detach; 366203288Srnoland } 367203288Srnoland 368203288Srnoland URTWN_LOCK(sc); 369203288Srnoland 370203288Srnoland error = urtwn_read_chipid(sc); 371203288Srnoland if (error) { 372203288Srnoland device_printf(sc->sc_dev, "unsupported test chip\n"); 373203288Srnoland URTWN_UNLOCK(sc); 374203288Srnoland goto detach; 375203288Srnoland } 376203288Srnoland 377203288Srnoland /* Determine number of Tx/Rx chains. */ 378203288Srnoland if (sc->chip & URTWN_CHIP_92C) { 379203288Srnoland sc->ntxchains = (sc->chip & URTWN_CHIP_92C_1T2R) ? 1 : 2; 380203288Srnoland sc->nrxchains = 2; 381203288Srnoland } else { 382203288Srnoland sc->ntxchains = 1; 383203288Srnoland sc->nrxchains = 1; 384203288Srnoland } 385203288Srnoland urtwn_read_rom(sc); 386203288Srnoland 387203288Srnoland device_printf(sc->sc_dev, "MAC/BB RTL%s, RF 6052 %dT%dR\n", 388203288Srnoland (sc->chip & URTWN_CHIP_92C) ? "8192CU" : 389203288Srnoland (sc->board_type == R92C_BOARD_TYPE_HIGHPA) ? "8188RU" : 390203288Srnoland (sc->board_type == R92C_BOARD_TYPE_MINICARD) ? "8188CE-VAU" : 391203288Srnoland "8188CUS", sc->ntxchains, sc->nrxchains); 392203288Srnoland 393203288Srnoland URTWN_UNLOCK(sc); 394203288Srnoland 395203288Srnoland ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 396203288Srnoland if (ifp == NULL) { 397203288Srnoland device_printf(sc->sc_dev, "can not if_alloc()\n"); 398203288Srnoland goto detach; 399203288Srnoland } 400203288Srnoland ic = ifp->if_l2com; 401203288Srnoland 402203288Srnoland ifp->if_softc = sc; 403203288Srnoland if_initname(ifp, "urtwn", device_get_unit(sc->sc_dev)); 404203288Srnoland ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 405203288Srnoland ifp->if_init = urtwn_init; 406203288Srnoland ifp->if_ioctl = urtwn_ioctl; 407203288Srnoland ifp->if_start = urtwn_start; 408203288Srnoland IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 409203288Srnoland ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; 410203288Srnoland IFQ_SET_READY(&ifp->if_snd); 411203288Srnoland 412203288Srnoland ic->ic_ifp = ifp; 413203288Srnoland ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 414203288Srnoland ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ 415203288Srnoland 416203288Srnoland /* set device capabilities */ 417203288Srnoland ic->ic_caps = 418203288Srnoland IEEE80211_C_STA /* station mode */ 419203288Srnoland | IEEE80211_C_MONITOR /* monitor mode */ 420203288Srnoland | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 421203288Srnoland | IEEE80211_C_SHSLOT /* short slot time supported */ 422203288Srnoland | IEEE80211_C_BGSCAN /* capable of bg scanning */ 423203288Srnoland | IEEE80211_C_WPA /* 802.11i */ 424203288Srnoland ; 425203288Srnoland 426203288Srnoland bands = 0; 427203288Srnoland setbit(&bands, IEEE80211_MODE_11B); 428203288Srnoland setbit(&bands, IEEE80211_MODE_11G); 429203288Srnoland ieee80211_init_channels(ic, NULL, &bands); 430203288Srnoland 431203288Srnoland ieee80211_ifattach(ic, sc->sc_bssid); 432203288Srnoland ic->ic_raw_xmit = urtwn_raw_xmit; 433203288Srnoland ic->ic_scan_start = urtwn_scan_start; 434203288Srnoland ic->ic_scan_end = urtwn_scan_end; 435203288Srnoland ic->ic_set_channel = urtwn_set_channel; 436203288Srnoland 437203288Srnoland ic->ic_vap_create = urtwn_vap_create; 438203288Srnoland ic->ic_vap_delete = urtwn_vap_delete; 439203288Srnoland ic->ic_update_mcast = urtwn_update_mcast; 440203288Srnoland 441203288Srnoland ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, 442203288Srnoland sizeof(sc->sc_txtap), URTWN_TX_RADIOTAP_PRESENT, 443203288Srnoland &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), 444203288Srnoland URTWN_RX_RADIOTAP_PRESENT); 445203288Srnoland 446203288Srnoland if (bootverbose) 447203288Srnoland ieee80211_announce(ic); 448203288Srnoland 449203288Srnoland return (0); 450203288Srnoland 451203288Srnolanddetach: 452203288Srnoland urtwn_detach(self); 453203288Srnoland return (ENXIO); /* failure */ 454203288Srnoland} 455203288Srnoland 456203288Srnolandstatic int 457203288Srnolandurtwn_detach(device_t self) 458203288Srnoland{ 459203288Srnoland struct urtwn_softc *sc = device_get_softc(self); 460203288Srnoland struct ifnet *ifp = sc->sc_ifp; 461203288Srnoland struct ieee80211com *ic = ifp->if_l2com; 462203288Srnoland unsigned int x; 463203288Srnoland 464203288Srnoland /* Prevent further ioctls. */ 465203288Srnoland URTWN_LOCK(sc); 466203288Srnoland sc->sc_flags |= URTWN_DETACHED; 467203288Srnoland URTWN_UNLOCK(sc); 468203288Srnoland 469203288Srnoland urtwn_stop(ifp); 470203288Srnoland 471203288Srnoland callout_drain(&sc->sc_watchdog_ch); 472203288Srnoland 473203288Srnoland /* Prevent further allocations from RX/TX data lists. */ 474203288Srnoland URTWN_LOCK(sc); 475203288Srnoland STAILQ_INIT(&sc->sc_tx_active); 476203288Srnoland STAILQ_INIT(&sc->sc_tx_inactive); 477203288Srnoland STAILQ_INIT(&sc->sc_tx_pending); 478203288Srnoland 479203288Srnoland STAILQ_INIT(&sc->sc_rx_active); 480203288Srnoland STAILQ_INIT(&sc->sc_rx_inactive); 481203288Srnoland URTWN_UNLOCK(sc); 482203288Srnoland 483203288Srnoland /* drain USB transfers */ 484203288Srnoland for (x = 0; x != URTWN_N_TRANSFER; x++) 485203288Srnoland usbd_transfer_drain(sc->sc_xfer[x]); 486203288Srnoland 487203288Srnoland /* Free data buffers. */ 488203288Srnoland URTWN_LOCK(sc); 489203288Srnoland urtwn_free_tx_list(sc); 490203288Srnoland urtwn_free_rx_list(sc); 491203288Srnoland URTWN_UNLOCK(sc); 492203288Srnoland 493203288Srnoland /* stop all USB transfers */ 494203288Srnoland usbd_transfer_unsetup(sc->sc_xfer, URTWN_N_TRANSFER); 495203288Srnoland ieee80211_ifdetach(ic); 496203288Srnoland 497203288Srnoland if_free(ifp); 498203288Srnoland mtx_destroy(&sc->sc_mtx); 499203288Srnoland 500203288Srnoland return (0); 501203288Srnoland} 502203288Srnoland 503203288Srnolandstatic void 504203288Srnolandurtwn_free_tx_list(struct urtwn_softc *sc) 505203288Srnoland{ 506203288Srnoland urtwn_free_list(sc, sc->sc_tx, URTWN_TX_LIST_COUNT); 507203288Srnoland} 508203288Srnoland 509203288Srnolandstatic void 510203288Srnolandurtwn_free_rx_list(struct urtwn_softc *sc) 511203288Srnoland{ 512203288Srnoland urtwn_free_list(sc, sc->sc_rx, URTWN_RX_LIST_COUNT); 513203288Srnoland} 514203288Srnoland 515203288Srnolandstatic void 516203288Srnolandurtwn_free_list(struct urtwn_softc *sc, struct urtwn_data data[], int ndata) 517203288Srnoland{ 518203288Srnoland int i; 519203288Srnoland 520203288Srnoland for (i = 0; i < ndata; i++) { 521203288Srnoland struct urtwn_data *dp = &data[i]; 522203288Srnoland 523203288Srnoland if (dp->buf != NULL) { 524203288Srnoland free(dp->buf, M_USBDEV); 525203288Srnoland dp->buf = NULL; 526203288Srnoland } 527203288Srnoland if (dp->ni != NULL) { 528203288Srnoland ieee80211_free_node(dp->ni); 529203288Srnoland dp->ni = NULL; 530203288Srnoland } 531203288Srnoland } 532203288Srnoland} 533203288Srnoland 534203288Srnolandstatic usb_error_t 535203288Srnolandurtwn_do_request(struct urtwn_softc *sc, struct usb_device_request *req, 536203288Srnoland void *data) 537203288Srnoland{ 538203288Srnoland usb_error_t err; 539203288Srnoland int ntries = 10; 540203288Srnoland 541203288Srnoland URTWN_ASSERT_LOCKED(sc); 542203288Srnoland 543203288Srnoland while (ntries--) { 544203288Srnoland err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx, 545203288Srnoland req, data, 0, NULL, 250 /* ms */); 546203288Srnoland if (err == 0) 547203288Srnoland break; 548203288Srnoland 549203288Srnoland DPRINTFN(1, "Control request failed, %s (retrying)\n", 550203288Srnoland usbd_errstr(err)); 551203288Srnoland usb_pause_mtx(&sc->sc_mtx, hz / 100); 552203288Srnoland } 553203288Srnoland return (err); 554203288Srnoland} 555203288Srnoland 556203288Srnolandstatic struct ieee80211vap * 557203288Srnolandurtwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 558203288Srnoland enum ieee80211_opmode opmode, int flags, 559203288Srnoland const uint8_t bssid[IEEE80211_ADDR_LEN], 560203288Srnoland const uint8_t mac[IEEE80211_ADDR_LEN]) 561203288Srnoland{ 562203288Srnoland struct urtwn_vap *uvp; 563203288Srnoland struct ieee80211vap *vap; 564203288Srnoland 565203288Srnoland if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 566203288Srnoland return (NULL); 567203288Srnoland 568203288Srnoland uvp = (struct urtwn_vap *) malloc(sizeof(struct urtwn_vap), 569203288Srnoland M_80211_VAP, M_NOWAIT | M_ZERO); 570203288Srnoland if (uvp == NULL) 571203288Srnoland return (NULL); 572203288Srnoland vap = &uvp->vap; 573203288Srnoland /* enable s/w bmiss handling for sta mode */ 574203288Srnoland 575203288Srnoland if (ieee80211_vap_setup(ic, vap, name, unit, opmode, 576203288Srnoland flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) { 577203288Srnoland /* out of memory */ 578203288Srnoland free(uvp, M_80211_VAP); 579203288Srnoland return (NULL); 580203288Srnoland } 581203288Srnoland 582203288Srnoland /* override state transition machine */ 583203288Srnoland uvp->newstate = vap->iv_newstate; 584203288Srnoland vap->iv_newstate = urtwn_newstate; 585203288Srnoland 586203288Srnoland /* complete setup */ 587203288Srnoland ieee80211_vap_attach(vap, ieee80211_media_change, 588203288Srnoland ieee80211_media_status); 589203288Srnoland ic->ic_opmode = opmode; 590203288Srnoland return (vap); 591203288Srnoland} 592203288Srnoland 593203288Srnolandstatic void 594203288Srnolandurtwn_vap_delete(struct ieee80211vap *vap) 595203288Srnoland{ 596203288Srnoland struct urtwn_vap *uvp = URTWN_VAP(vap); 597203288Srnoland 598203288Srnoland ieee80211_vap_detach(vap); 599203288Srnoland free(uvp, M_80211_VAP); 600203288Srnoland} 601203288Srnoland 602203288Srnolandstatic struct mbuf * 603203288Srnolandurtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p) 604203288Srnoland{ 605203288Srnoland struct ifnet *ifp = sc->sc_ifp; 606203288Srnoland struct ieee80211com *ic = ifp->if_l2com; 607203288Srnoland struct ieee80211_frame *wh; 608203288Srnoland struct mbuf *m; 609203288Srnoland struct r92c_rx_stat *stat; 610203288Srnoland uint32_t rxdw0, rxdw3; 611203288Srnoland uint8_t rate; 612203288Srnoland int8_t rssi = 0; 613203288Srnoland int infosz; 614203288Srnoland 615203288Srnoland /* 616203288Srnoland * don't pass packets to the ieee80211 framework if the driver isn't 617203288Srnoland * RUNNING. 618203288Srnoland */ 619203288Srnoland if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) 620203288Srnoland return (NULL); 621203288Srnoland 622203288Srnoland stat = (struct r92c_rx_stat *)buf; 623203288Srnoland rxdw0 = le32toh(stat->rxdw0); 624203288Srnoland rxdw3 = le32toh(stat->rxdw3); 625203288Srnoland 626203288Srnoland if (rxdw0 & (R92C_RXDW0_CRCERR | R92C_RXDW0_ICVERR)) { 627203288Srnoland /* 628203288Srnoland * This should not happen since we setup our Rx filter 629203288Srnoland * to not receive these frames. 630203288Srnoland */ 631203288Srnoland ifp->if_ierrors++; 632203288Srnoland return (NULL); 633203288Srnoland } 634203288Srnoland 635203288Srnoland rate = MS(rxdw3, R92C_RXDW3_RATE); 636203288Srnoland infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8; 637203288Srnoland 638203288Srnoland /* Get RSSI from PHY status descriptor if present. */ 639203288Srnoland if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) { 640203288Srnoland rssi = urtwn_get_rssi(sc, rate, &stat[1]); 641203288Srnoland /* Update our average RSSI. */ 642203288Srnoland urtwn_update_avgrssi(sc, rate, rssi); 643203288Srnoland /* 644203288Srnoland * Convert the RSSI to a range that will be accepted 645203288Srnoland * by net80211. 646203288Srnoland */ 647203288Srnoland rssi = URTWN_RSSI(rssi); 648203288Srnoland } 649203288Srnoland 650203288Srnoland m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 651203288Srnoland if (m == NULL) { 652203288Srnoland device_printf(sc->sc_dev, "could not create RX mbuf\n"); 653203288Srnoland return (NULL); 654203288Srnoland } 655203288Srnoland 656203288Srnoland /* Finalize mbuf. */ 657203288Srnoland m->m_pkthdr.rcvif = ifp; 658203288Srnoland wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz); 659203288Srnoland memcpy(mtod(m, uint8_t *), wh, pktlen); 660203288Srnoland m->m_pkthdr.len = m->m_len = pktlen; 661203288Srnoland 662203288Srnoland if (ieee80211_radiotap_active(ic)) { 663203288Srnoland struct urtwn_rx_radiotap_header *tap = &sc->sc_rxtap; 664203288Srnoland 665203288Srnoland tap->wr_flags = 0; 666203288Srnoland /* Map HW rate index to 802.11 rate. */ 667203288Srnoland if (!(rxdw3 & R92C_RXDW3_HT)) { 668203288Srnoland switch (rate) { 669203288Srnoland /* CCK. */ 670203288Srnoland case 0: tap->wr_rate = 2; break; 671203288Srnoland case 1: tap->wr_rate = 4; break; 672203288Srnoland case 2: tap->wr_rate = 11; break; 673203288Srnoland case 3: tap->wr_rate = 22; break; 674203288Srnoland /* OFDM. */ 675203288Srnoland case 4: tap->wr_rate = 12; break; 676203288Srnoland case 5: tap->wr_rate = 18; break; 677203288Srnoland case 6: tap->wr_rate = 24; break; 678203288Srnoland case 7: tap->wr_rate = 36; break; 679203288Srnoland case 8: tap->wr_rate = 48; break; 680203288Srnoland case 9: tap->wr_rate = 72; break; 681203288Srnoland case 10: tap->wr_rate = 96; break; 682203288Srnoland case 11: tap->wr_rate = 108; break; 683203288Srnoland } 684203288Srnoland } else if (rate >= 12) { /* MCS0~15. */ 685203288Srnoland /* Bit 7 set means HT MCS instead of rate. */ 686203288Srnoland tap->wr_rate = 0x80 | (rate - 12); 687203288Srnoland } 688203288Srnoland tap->wr_dbm_antsignal = rssi; 689203288Srnoland tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); 690203288Srnoland tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); 691203288Srnoland } 692203288Srnoland 693203288Srnoland *rssi_p = rssi; 694203288Srnoland 695203288Srnoland return (m); 696203288Srnoland} 697203288Srnoland 698203288Srnolandstatic struct mbuf * 699203288Srnolandurtwn_rxeof(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi, 700203288Srnoland int8_t *nf) 701203288Srnoland{ 702203288Srnoland struct urtwn_softc *sc = data->sc; 703203288Srnoland struct ifnet *ifp = sc->sc_ifp; 704203288Srnoland struct r92c_rx_stat *stat; 705203288Srnoland struct mbuf *m, *m0 = NULL, *prevm = NULL; 706203288Srnoland uint32_t rxdw0; 707203288Srnoland uint8_t *buf; 708203288Srnoland int len, totlen, pktlen, infosz, npkts; 709203288Srnoland 710203288Srnoland usbd_xfer_status(xfer, &len, NULL, NULL, NULL); 711203288Srnoland 712203288Srnoland if (len < sizeof(*stat)) { 713203288Srnoland ifp->if_ierrors++; 714203288Srnoland return (NULL); 715203288Srnoland } 716203288Srnoland 717203288Srnoland buf = data->buf; 718203288Srnoland /* Get the number of encapsulated frames. */ 719203288Srnoland stat = (struct r92c_rx_stat *)buf; 720203288Srnoland npkts = MS(le32toh(stat->rxdw2), R92C_RXDW2_PKTCNT); 721203288Srnoland DPRINTFN(6, "Rx %d frames in one chunk\n", npkts); 722203288Srnoland 723203288Srnoland /* Process all of them. */ 724203288Srnoland while (npkts-- > 0) { 725203288Srnoland if (len < sizeof(*stat)) 726203288Srnoland break; 727203288Srnoland stat = (struct r92c_rx_stat *)buf; 728203288Srnoland rxdw0 = le32toh(stat->rxdw0); 729203288Srnoland 730203288Srnoland pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN); 731203288Srnoland if (pktlen == 0) 732203288Srnoland break; 733203288Srnoland 734203288Srnoland infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8; 735203288Srnoland 736203288Srnoland /* Make sure everything fits in xfer. */ 737203288Srnoland totlen = sizeof(*stat) + infosz + pktlen; 738203288Srnoland if (totlen > len) 739203288Srnoland break; 740203288Srnoland 741203288Srnoland m = urtwn_rx_frame(sc, buf, pktlen, rssi); 742203288Srnoland if (m0 == NULL) 743203288Srnoland m0 = m; 744203288Srnoland if (prevm == NULL) 745203288Srnoland prevm = m; 746203288Srnoland else { 747203288Srnoland prevm->m_next = m; 748203288Srnoland prevm = m; 749203288Srnoland } 750203288Srnoland 751203288Srnoland /* Next chunk is 128-byte aligned. */ 752203288Srnoland totlen = (totlen + 127) & ~127; 753203288Srnoland buf += totlen; 754203288Srnoland len -= totlen; 755203288Srnoland } 756203288Srnoland 757203288Srnoland return (m0); 758203288Srnoland} 759203288Srnoland 760203288Srnolandstatic void 761203288Srnolandurtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) 762203288Srnoland{ 763203288Srnoland struct urtwn_softc *sc = usbd_xfer_softc(xfer); 764203288Srnoland struct ifnet *ifp = sc->sc_ifp; 765203288Srnoland struct ieee80211com *ic = ifp->if_l2com; 766203288Srnoland struct ieee80211_frame *wh; 767203288Srnoland struct ieee80211_node *ni; 768203288Srnoland struct mbuf *m = NULL, *next; 769203288Srnoland struct urtwn_data *data; 770203288Srnoland int8_t nf; 771203288Srnoland int rssi = 1; 772203288Srnoland 773203288Srnoland URTWN_ASSERT_LOCKED(sc); 774203288Srnoland 775203288Srnoland switch (USB_GET_STATE(xfer)) { 776203288Srnoland case USB_ST_TRANSFERRED: 777203288Srnoland data = STAILQ_FIRST(&sc->sc_rx_active); 778203288Srnoland if (data == NULL) 779203288Srnoland goto tr_setup; 780203288Srnoland STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next); 781203288Srnoland m = urtwn_rxeof(xfer, data, &rssi, &nf); 782203288Srnoland STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); 783203288Srnoland /* FALLTHROUGH */ 784203288Srnoland case USB_ST_SETUP: 785203288Srnolandtr_setup: 786203288Srnoland data = STAILQ_FIRST(&sc->sc_rx_inactive); 787203288Srnoland if (data == NULL) { 788203288Srnoland KASSERT(m == NULL, ("mbuf isn't NULL")); 789203288Srnoland return; 790203288Srnoland } 791203288Srnoland STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next); 792203288Srnoland STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next); 793203288Srnoland usbd_xfer_set_frame_data(xfer, 0, data->buf, 794203288Srnoland usbd_xfer_max_len(xfer)); 795203288Srnoland usbd_transfer_submit(xfer); 796203288Srnoland 797203288Srnoland /* 798203288Srnoland * To avoid LOR we should unlock our private mutex here to call 799203288Srnoland * ieee80211_input() because here is at the end of a USB 800203288Srnoland * callback and safe to unlock. 801203288Srnoland */ 802203288Srnoland URTWN_UNLOCK(sc); 803203288Srnoland while (m != NULL) { 804203288Srnoland next = m->m_next; 805203288Srnoland m->m_next = NULL; 806203288Srnoland wh = mtod(m, struct ieee80211_frame *); 807203288Srnoland ni = ieee80211_find_rxnode(ic, 808203288Srnoland (struct ieee80211_frame_min *)wh); 809203288Srnoland nf = URTWN_NOISE_FLOOR; 810203288Srnoland if (ni != NULL) { 811203288Srnoland (void)ieee80211_input(ni, m, rssi, nf); 812203288Srnoland ieee80211_free_node(ni); 813203288Srnoland } else 814203288Srnoland (void)ieee80211_input_all(ic, m, rssi, nf); 815203288Srnoland m = next; 816203288Srnoland } 817203288Srnoland URTWN_LOCK(sc); 818203288Srnoland break; 819203288Srnoland default: 820203288Srnoland /* needs it to the inactive queue due to a error. */ 821203288Srnoland data = STAILQ_FIRST(&sc->sc_rx_active); 822203288Srnoland if (data != NULL) { 823203288Srnoland STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next); 824203288Srnoland STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); 825203288Srnoland } 826203288Srnoland if (error != USB_ERR_CANCELLED) { 827203288Srnoland usbd_xfer_set_stall(xfer); 828203288Srnoland ifp->if_ierrors++; 829203288Srnoland goto tr_setup; 830203288Srnoland } 831203288Srnoland break; 832203288Srnoland } 833203288Srnoland} 834203288Srnoland 835203288Srnolandstatic void 836203288Srnolandurtwn_txeof(struct usb_xfer *xfer, struct urtwn_data *data) 837203288Srnoland{ 838203288Srnoland struct urtwn_softc *sc = usbd_xfer_softc(xfer); 839203288Srnoland struct ifnet *ifp = sc->sc_ifp; 840203288Srnoland struct mbuf *m; 841203288Srnoland 842203288Srnoland URTWN_ASSERT_LOCKED(sc); 843203288Srnoland 844203288Srnoland /* 845203288Srnoland * Do any tx complete callback. Note this must be done before releasing 846203288Srnoland * the node reference. 847203288Srnoland */ 848203288Srnoland if (data->m) { 849203288Srnoland m = data->m; 850203288Srnoland if (m->m_flags & M_TXCB) { 851203288Srnoland /* XXX status? */ 852203288Srnoland ieee80211_process_callback(data->ni, m, 0); 853203288Srnoland } 854203288Srnoland m_freem(m); 855203288Srnoland data->m = NULL; 856203288Srnoland } 857203288Srnoland if (data->ni) { 858203288Srnoland ieee80211_free_node(data->ni); 859203288Srnoland data->ni = NULL; 860203288Srnoland } 861203288Srnoland sc->sc_txtimer = 0; 862203288Srnoland ifp->if_opackets++; 863203288Srnoland ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 864203288Srnoland} 865203288Srnoland 866203288Srnolandstatic void 867203288Srnolandurtwn_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) 868203288Srnoland{ 869203288Srnoland struct urtwn_softc *sc = usbd_xfer_softc(xfer); 870203288Srnoland struct ifnet *ifp = sc->sc_ifp; 871203288Srnoland struct urtwn_data *data; 872203288Srnoland 873203288Srnoland URTWN_ASSERT_LOCKED(sc); 874203288Srnoland 875203288Srnoland switch (USB_GET_STATE(xfer)){ 876203288Srnoland case USB_ST_TRANSFERRED: 877203288Srnoland data = STAILQ_FIRST(&sc->sc_tx_active); 878203288Srnoland if (data == NULL) 879203288Srnoland goto tr_setup; 880203288Srnoland STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next); 881203288Srnoland urtwn_txeof(xfer, data); 882203288Srnoland STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next); 883203288Srnoland /* FALLTHROUGH */ 884203288Srnoland case USB_ST_SETUP: 885203288Srnolandtr_setup: 886203288Srnoland data = STAILQ_FIRST(&sc->sc_tx_pending); 887203288Srnoland if (data == NULL) { 888203288Srnoland DPRINTF("%s: empty pending queue\n", __func__); 889203288Srnoland return; 890203288Srnoland } 891203288Srnoland STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next); 892203288Srnoland STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next); 893203288Srnoland usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen); 894203288Srnoland usbd_transfer_submit(xfer); 895203288Srnoland urtwn_start_locked(ifp, sc); 896203288Srnoland break; 897203288Srnoland default: 898203288Srnoland data = STAILQ_FIRST(&sc->sc_tx_active); 899203288Srnoland if (data == NULL) 900203288Srnoland goto tr_setup; 901203288Srnoland if (data->ni != NULL) { 902203288Srnoland ieee80211_free_node(data->ni); 903203288Srnoland data->ni = NULL; 904203288Srnoland ifp->if_oerrors++; 905203288Srnoland } 906203288Srnoland if (error != USB_ERR_CANCELLED) { 907203288Srnoland usbd_xfer_set_stall(xfer); 908203288Srnoland goto tr_setup; 909203288Srnoland } 910203288Srnoland break; 911203288Srnoland } 912203288Srnoland} 913203288Srnoland 914203288Srnolandstatic struct urtwn_data * 915203288Srnoland_urtwn_getbuf(struct urtwn_softc *sc) 916203288Srnoland{ 917203288Srnoland struct urtwn_data *bf; 918203288Srnoland 919203288Srnoland bf = STAILQ_FIRST(&sc->sc_tx_inactive); 920203288Srnoland if (bf != NULL) 921203288Srnoland STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next); 922203288Srnoland else 923203288Srnoland bf = NULL; 924203288Srnoland if (bf == NULL) 925203288Srnoland DPRINTF("%s: %s\n", __func__, "out of xmit buffers"); 926203288Srnoland return (bf); 927203288Srnoland} 928203288Srnoland 929203288Srnolandstatic struct urtwn_data * 930203288Srnolandurtwn_getbuf(struct urtwn_softc *sc) 931203288Srnoland{ 932203288Srnoland struct urtwn_data *bf; 933203288Srnoland 934203288Srnoland URTWN_ASSERT_LOCKED(sc); 935203288Srnoland 936203288Srnoland bf = _urtwn_getbuf(sc); 937203288Srnoland if (bf == NULL) { 938203288Srnoland struct ifnet *ifp = sc->sc_ifp; 939203288Srnoland DPRINTF("%s: stop queue\n", __func__); 940203288Srnoland ifp->if_drv_flags |= IFF_DRV_OACTIVE; 941203288Srnoland } 942203288Srnoland return (bf); 943203288Srnoland} 944203288Srnoland 945203288Srnolandstatic int 946203288Srnolandurtwn_write_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf, 947203288Srnoland int len) 948203288Srnoland{ 949203288Srnoland usb_device_request_t req; 950203288Srnoland 951203288Srnoland req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 952203288Srnoland req.bRequest = R92C_REQ_REGS; 953203288Srnoland USETW(req.wValue, addr); 954203288Srnoland USETW(req.wIndex, 0); 955203288Srnoland USETW(req.wLength, len); 956203288Srnoland return (urtwn_do_request(sc, &req, buf)); 957203288Srnoland} 958203288Srnoland 959203288Srnolandstatic void 960203288Srnolandurtwn_write_1(struct urtwn_softc *sc, uint16_t addr, uint8_t val) 961203288Srnoland{ 962203288Srnoland urtwn_write_region_1(sc, addr, &val, 1); 963203288Srnoland} 964203288Srnoland 965203288Srnoland 966203288Srnolandstatic void 967203288Srnolandurtwn_write_2(struct urtwn_softc *sc, uint16_t addr, uint16_t val) 968203288Srnoland{ 969203288Srnoland val = htole16(val); 970203288Srnoland urtwn_write_region_1(sc, addr, (uint8_t *)&val, 2); 971203288Srnoland} 972203288Srnoland 973203288Srnolandstatic void 974203288Srnolandurtwn_write_4(struct urtwn_softc *sc, uint16_t addr, uint32_t val) 975203288Srnoland{ 976203288Srnoland val = htole32(val); 977203288Srnoland urtwn_write_region_1(sc, addr, (uint8_t *)&val, 4); 978203288Srnoland} 979203288Srnoland 980203288Srnolandstatic int 981203288Srnolandurtwn_read_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf, 982203288Srnoland int len) 983203288Srnoland{ 984203288Srnoland usb_device_request_t req; 985203288Srnoland 986203288Srnoland req.bmRequestType = UT_READ_VENDOR_DEVICE; 987203288Srnoland req.bRequest = R92C_REQ_REGS; 988203288Srnoland USETW(req.wValue, addr); 989203288Srnoland USETW(req.wIndex, 0); 990203288Srnoland USETW(req.wLength, len); 991203288Srnoland return (urtwn_do_request(sc, &req, buf)); 992203288Srnoland} 993203288Srnoland 994203288Srnolandstatic uint8_t 995203288Srnolandurtwn_read_1(struct urtwn_softc *sc, uint16_t addr) 996203288Srnoland{ 997203288Srnoland uint8_t val; 998203288Srnoland 999203288Srnoland if (urtwn_read_region_1(sc, addr, &val, 1) != 0) 1000203288Srnoland return (0xff); 1001203288Srnoland return (val); 1002203288Srnoland} 1003203288Srnoland 1004203288Srnolandstatic uint16_t 1005203288Srnolandurtwn_read_2(struct urtwn_softc *sc, uint16_t addr) 1006203288Srnoland{ 1007203288Srnoland uint16_t val; 1008203288Srnoland 1009203288Srnoland if (urtwn_read_region_1(sc, addr, (uint8_t *)&val, 2) != 0) 1010203288Srnoland return (0xffff); 1011203288Srnoland return (le16toh(val)); 1012203288Srnoland} 1013203288Srnoland 1014203288Srnolandstatic uint32_t 1015203288Srnolandurtwn_read_4(struct urtwn_softc *sc, uint16_t addr) 1016203288Srnoland{ 1017203288Srnoland uint32_t val; 1018203288Srnoland 1019203288Srnoland if (urtwn_read_region_1(sc, addr, (uint8_t *)&val, 4) != 0) 1020203288Srnoland return (0xffffffff); 1021203288Srnoland return (le32toh(val)); 1022203288Srnoland} 1023203288Srnoland 1024203288Srnolandstatic int 1025203288Srnolandurtwn_fw_cmd(struct urtwn_softc *sc, uint8_t id, const void *buf, int len) 1026203288Srnoland{ 1027203288Srnoland struct r92c_fw_cmd cmd; 1028203288Srnoland int ntries; 1029203288Srnoland 1030203288Srnoland /* Wait for current FW box to be empty. */ 1031203288Srnoland for (ntries = 0; ntries < 100; ntries++) { 1032203288Srnoland if (!(urtwn_read_1(sc, R92C_HMETFR) & (1 << sc->fwcur))) 1033203288Srnoland break; 1034203288Srnoland DELAY(1); 1035203288Srnoland } 1036203288Srnoland if (ntries == 100) { 1037203288Srnoland device_printf(sc->sc_dev, 1038203288Srnoland "could not send firmware command\n"); 1039203288Srnoland return (ETIMEDOUT); 1040203288Srnoland } 1041203288Srnoland memset(&cmd, 0, sizeof(cmd)); 1042203288Srnoland cmd.id = id; 1043203288Srnoland if (len > 3) 1044203288Srnoland cmd.id |= R92C_CMD_FLAG_EXT; 1045203288Srnoland KASSERT(len <= sizeof(cmd.msg), ("urtwn_fw_cmd\n")); 1046203288Srnoland memcpy(cmd.msg, buf, len); 1047203288Srnoland 1048203288Srnoland /* Write the first word last since that will trigger the FW. */ 1049203288Srnoland urtwn_write_region_1(sc, R92C_HMEBOX_EXT(sc->fwcur), 1050203288Srnoland (uint8_t *)&cmd + 4, 2); 1051203288Srnoland urtwn_write_region_1(sc, R92C_HMEBOX(sc->fwcur), 1052203288Srnoland (uint8_t *)&cmd + 0, 4); 1053203288Srnoland 1054203288Srnoland sc->fwcur = (sc->fwcur + 1) % R92C_H2C_NBOX; 1055203288Srnoland return (0); 1056203288Srnoland} 1057203288Srnoland 1058203288Srnolandstatic void 1059203288Srnolandurtwn_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr, uint32_t val) 1060203288Srnoland{ 1061203288Srnoland urtwn_bb_write(sc, R92C_LSSI_PARAM(chain), 1062203288Srnoland SM(R92C_LSSI_PARAM_ADDR, addr) | 1063203288Srnoland SM(R92C_LSSI_PARAM_DATA, val)); 1064203288Srnoland} 1065203288Srnoland 1066203288Srnolandstatic uint32_t 1067203288Srnolandurtwn_rf_read(struct urtwn_softc *sc, int chain, uint8_t addr) 1068203288Srnoland{ 1069203288Srnoland uint32_t reg[R92C_MAX_CHAINS], val; 1070203288Srnoland 1071203288Srnoland reg[0] = urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)); 1072203288Srnoland if (chain != 0) 1073203288Srnoland reg[chain] = urtwn_bb_read(sc, R92C_HSSI_PARAM2(chain)); 1074203288Srnoland 1075203288Srnoland urtwn_bb_write(sc, R92C_HSSI_PARAM2(0), 1076203288Srnoland reg[0] & ~R92C_HSSI_PARAM2_READ_EDGE); 1077203288Srnoland DELAY(1000); 1078203288Srnoland 1079203288Srnoland urtwn_bb_write(sc, R92C_HSSI_PARAM2(chain), 1080203288Srnoland RW(reg[chain], R92C_HSSI_PARAM2_READ_ADDR, addr) | 1081203288Srnoland R92C_HSSI_PARAM2_READ_EDGE); 1082203288Srnoland DELAY(1000); 1083203288Srnoland 1084203288Srnoland urtwn_bb_write(sc, R92C_HSSI_PARAM2(0), 1085203288Srnoland reg[0] | R92C_HSSI_PARAM2_READ_EDGE); 1086203288Srnoland DELAY(1000); 1087203288Srnoland 1088203288Srnoland if (urtwn_bb_read(sc, R92C_HSSI_PARAM1(chain)) & R92C_HSSI_PARAM1_PI) 1089203288Srnoland val = urtwn_bb_read(sc, R92C_HSPI_READBACK(chain)); 1090203288Srnoland else 1091203288Srnoland val = urtwn_bb_read(sc, R92C_LSSI_READBACK(chain)); 1092203288Srnoland return (MS(val, R92C_LSSI_READBACK_DATA)); 1093203288Srnoland} 1094203288Srnoland 1095203288Srnolandstatic int 1096203288Srnolandurtwn_llt_write(struct urtwn_softc *sc, uint32_t addr, uint32_t data) 1097203288Srnoland{ 1098203288Srnoland int ntries; 1099203288Srnoland 1100203288Srnoland urtwn_write_4(sc, R92C_LLT_INIT, 1101203288Srnoland SM(R92C_LLT_INIT_OP, R92C_LLT_INIT_OP_WRITE) | 1102203288Srnoland SM(R92C_LLT_INIT_ADDR, addr) | 1103203288Srnoland SM(R92C_LLT_INIT_DATA, data)); 1104203288Srnoland /* Wait for write operation to complete. */ 1105203288Srnoland for (ntries = 0; ntries < 20; ntries++) { 1106203288Srnoland if (MS(urtwn_read_4(sc, R92C_LLT_INIT), R92C_LLT_INIT_OP) == 1107203288Srnoland R92C_LLT_INIT_OP_NO_ACTIVE) 1108203288Srnoland return (0); 1109203288Srnoland DELAY(5); 1110203288Srnoland } 1111203288Srnoland return (ETIMEDOUT); 1112203288Srnoland} 1113203288Srnoland 1114203288Srnolandstatic uint8_t 1115203288Srnolandurtwn_efuse_read_1(struct urtwn_softc *sc, uint16_t addr) 1116{ 1117 uint32_t reg; 1118 int ntries; 1119 1120 reg = urtwn_read_4(sc, R92C_EFUSE_CTRL); 1121 reg = RW(reg, R92C_EFUSE_CTRL_ADDR, addr); 1122 reg &= ~R92C_EFUSE_CTRL_VALID; 1123 urtwn_write_4(sc, R92C_EFUSE_CTRL, reg); 1124 /* Wait for read operation to complete. */ 1125 for (ntries = 0; ntries < 100; ntries++) { 1126 reg = urtwn_read_4(sc, R92C_EFUSE_CTRL); 1127 if (reg & R92C_EFUSE_CTRL_VALID) 1128 return (MS(reg, R92C_EFUSE_CTRL_DATA)); 1129 DELAY(5); 1130 } 1131 device_printf(sc->sc_dev, 1132 "could not read efuse byte at address 0x%x\n", addr); 1133 return (0xff); 1134} 1135 1136static void 1137urtwn_efuse_read(struct urtwn_softc *sc) 1138{ 1139 uint8_t *rom = (uint8_t *)&sc->rom; 1140 uint16_t addr = 0; 1141 uint32_t reg; 1142 uint8_t off, msk; 1143 int i; 1144 1145 reg = urtwn_read_2(sc, R92C_SYS_ISO_CTRL); 1146 if (!(reg & R92C_SYS_ISO_CTRL_PWC_EV12V)) { 1147 urtwn_write_2(sc, R92C_SYS_ISO_CTRL, 1148 reg | R92C_SYS_ISO_CTRL_PWC_EV12V); 1149 } 1150 reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN); 1151 if (!(reg & R92C_SYS_FUNC_EN_ELDR)) { 1152 urtwn_write_2(sc, R92C_SYS_FUNC_EN, 1153 reg | R92C_SYS_FUNC_EN_ELDR); 1154 } 1155 reg = urtwn_read_2(sc, R92C_SYS_CLKR); 1156 if ((reg & (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) != 1157 (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) { 1158 urtwn_write_2(sc, R92C_SYS_CLKR, 1159 reg | R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M); 1160 } 1161 memset(&sc->rom, 0xff, sizeof(sc->rom)); 1162 while (addr < 512) { 1163 reg = urtwn_efuse_read_1(sc, addr); 1164 if (reg == 0xff) 1165 break; 1166 addr++; 1167 off = reg >> 4; 1168 msk = reg & 0xf; 1169 for (i = 0; i < 4; i++) { 1170 if (msk & (1 << i)) 1171 continue; 1172 rom[off * 8 + i * 2 + 0] = 1173 urtwn_efuse_read_1(sc, addr); 1174 addr++; 1175 rom[off * 8 + i * 2 + 1] = 1176 urtwn_efuse_read_1(sc, addr); 1177 addr++; 1178 } 1179 } 1180#ifdef URTWN_DEBUG 1181 if (urtwn_debug >= 2) { 1182 /* Dump ROM content. */ 1183 printf("\n"); 1184 for (i = 0; i < sizeof(sc->rom); i++) 1185 printf("%02x:", rom[i]); 1186 printf("\n"); 1187 } 1188#endif 1189} 1190 1191static int 1192urtwn_read_chipid(struct urtwn_softc *sc) 1193{ 1194 uint32_t reg; 1195 1196 reg = urtwn_read_4(sc, R92C_SYS_CFG); 1197 if (reg & R92C_SYS_CFG_TRP_VAUX_EN) 1198 return (EIO); 1199 1200 if (reg & R92C_SYS_CFG_TYPE_92C) { 1201 sc->chip |= URTWN_CHIP_92C; 1202 /* Check if it is a castrated 8192C. */ 1203 if (MS(urtwn_read_4(sc, R92C_HPON_FSM), 1204 R92C_HPON_FSM_CHIP_BONDING_ID) == 1205 R92C_HPON_FSM_CHIP_BONDING_ID_92C_1T2R) 1206 sc->chip |= URTWN_CHIP_92C_1T2R; 1207 } 1208 if (reg & R92C_SYS_CFG_VENDOR_UMC) { 1209 sc->chip |= URTWN_CHIP_UMC; 1210 if (MS(reg, R92C_SYS_CFG_CHIP_VER_RTL) == 0) 1211 sc->chip |= URTWN_CHIP_UMC_A_CUT; 1212 } 1213 return (0); 1214} 1215 1216static void 1217urtwn_read_rom(struct urtwn_softc *sc) 1218{ 1219 struct r92c_rom *rom = &sc->rom; 1220 1221 /* Read full ROM image. */ 1222 urtwn_efuse_read(sc); 1223 1224 /* XXX Weird but this is what the vendor driver does. */ 1225 sc->pa_setting = urtwn_efuse_read_1(sc, 0x1fa); 1226 DPRINTF("PA setting=0x%x\n", sc->pa_setting); 1227 1228 sc->board_type = MS(rom->rf_opt1, R92C_ROM_RF1_BOARD_TYPE); 1229 1230 sc->regulatory = MS(rom->rf_opt1, R92C_ROM_RF1_REGULATORY); 1231 DPRINTF("regulatory type=%d\n", sc->regulatory); 1232 1233 IEEE80211_ADDR_COPY(sc->sc_bssid, rom->macaddr); 1234} 1235 1236/* 1237 * Initialize rate adaptation in firmware. 1238 */ 1239static int 1240urtwn_ra_init(struct urtwn_softc *sc) 1241{ 1242 static const uint8_t map[] = 1243 { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 }; 1244 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 1245 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 1246 struct ieee80211_node *ni; 1247 struct ieee80211_rateset *rs; 1248 struct r92c_fw_cmd_macid_cfg cmd; 1249 uint32_t rates, basicrates; 1250 uint8_t mode; 1251 int maxrate, maxbasicrate, error, i, j; 1252 1253 ni = ieee80211_ref_node(vap->iv_bss); 1254 rs = &ni->ni_rates; 1255 1256 /* Get normal and basic rates mask. */ 1257 rates = basicrates = 0; 1258 maxrate = maxbasicrate = 0; 1259 for (i = 0; i < rs->rs_nrates; i++) { 1260 /* Convert 802.11 rate to HW rate index. */ 1261 for (j = 0; j < nitems(map); j++) 1262 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == map[j]) 1263 break; 1264 if (j == nitems(map)) /* Unknown rate, skip. */ 1265 continue; 1266 rates |= 1 << j; 1267 if (j > maxrate) 1268 maxrate = j; 1269 if (rs->rs_rates[i] & IEEE80211_RATE_BASIC) { 1270 basicrates |= 1 << j; 1271 if (j > maxbasicrate) 1272 maxbasicrate = j; 1273 } 1274 } 1275 if (ic->ic_curmode == IEEE80211_MODE_11B) 1276 mode = R92C_RAID_11B; 1277 else 1278 mode = R92C_RAID_11BG; 1279 DPRINTF("mode=0x%x rates=0x%08x, basicrates=0x%08x\n", 1280 mode, rates, basicrates); 1281 1282 /* Set rates mask for group addressed frames. */ 1283 cmd.macid = URTWN_MACID_BC | URTWN_MACID_VALID; 1284 cmd.mask = htole32(mode << 28 | basicrates); 1285 error = urtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd)); 1286 if (error != 0) { 1287 ieee80211_free_node(ni); 1288 device_printf(sc->sc_dev, 1289 "could not add broadcast station\n"); 1290 return (error); 1291 } 1292 /* Set initial MRR rate. */ 1293 DPRINTF("maxbasicrate=%d\n", maxbasicrate); 1294 urtwn_write_1(sc, R92C_INIDATA_RATE_SEL(URTWN_MACID_BC), 1295 maxbasicrate); 1296 1297 /* Set rates mask for unicast frames. */ 1298 cmd.macid = URTWN_MACID_BSS | URTWN_MACID_VALID; 1299 cmd.mask = htole32(mode << 28 | rates); 1300 error = urtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd)); 1301 if (error != 0) { 1302 ieee80211_free_node(ni); 1303 device_printf(sc->sc_dev, "could not add BSS station\n"); 1304 return (error); 1305 } 1306 /* Set initial MRR rate. */ 1307 DPRINTF("maxrate=%d\n", maxrate); 1308 urtwn_write_1(sc, R92C_INIDATA_RATE_SEL(URTWN_MACID_BSS), 1309 maxrate); 1310 1311 /* Indicate highest supported rate. */ 1312 ni->ni_txrate = rs->rs_rates[rs->rs_nrates - 1]; 1313 ieee80211_free_node(ni); 1314 1315 return (0); 1316} 1317 1318void 1319urtwn_tsf_sync_enable(struct urtwn_softc *sc) 1320{ 1321 struct ifnet *ifp = sc->sc_ifp; 1322 struct ieee80211com *ic = ifp->if_l2com; 1323 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 1324 struct ieee80211_node *ni = vap->iv_bss; 1325 1326 uint64_t tsf; 1327 1328 /* Enable TSF synchronization. */ 1329 urtwn_write_1(sc, R92C_BCN_CTRL, 1330 urtwn_read_1(sc, R92C_BCN_CTRL) & ~R92C_BCN_CTRL_DIS_TSF_UDT0); 1331 1332 urtwn_write_1(sc, R92C_BCN_CTRL, 1333 urtwn_read_1(sc, R92C_BCN_CTRL) & ~R92C_BCN_CTRL_EN_BCN); 1334 1335 /* Set initial TSF. */ 1336 memcpy(&tsf, ni->ni_tstamp.data, 8); 1337 tsf = le64toh(tsf); 1338 tsf = tsf - (tsf % (vap->iv_bss->ni_intval * IEEE80211_DUR_TU)); 1339 tsf -= IEEE80211_DUR_TU; 1340 urtwn_write_4(sc, R92C_TSFTR + 0, tsf); 1341 urtwn_write_4(sc, R92C_TSFTR + 4, tsf >> 32); 1342 1343 urtwn_write_1(sc, R92C_BCN_CTRL, 1344 urtwn_read_1(sc, R92C_BCN_CTRL) | R92C_BCN_CTRL_EN_BCN); 1345} 1346 1347static void 1348urtwn_set_led(struct urtwn_softc *sc, int led, int on) 1349{ 1350 uint8_t reg; 1351 1352 if (led == URTWN_LED_LINK) { 1353 reg = urtwn_read_1(sc, R92C_LEDCFG0) & 0x70; 1354 if (!on) 1355 reg |= R92C_LEDCFG0_DIS; 1356 urtwn_write_1(sc, R92C_LEDCFG0, reg); 1357 sc->ledlink = on; /* Save LED state. */ 1358 } 1359} 1360 1361static int 1362urtwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1363{ 1364 struct urtwn_vap *uvp = URTWN_VAP(vap); 1365 struct ieee80211com *ic = vap->iv_ic; 1366 struct urtwn_softc *sc = ic->ic_ifp->if_softc; 1367 struct ieee80211_node *ni; 1368 enum ieee80211_state ostate; 1369 uint32_t reg; 1370 1371 ostate = vap->iv_state; 1372 DPRINTF("%s -> %s\n", ieee80211_state_name[ostate], 1373 ieee80211_state_name[nstate]); 1374 1375 IEEE80211_UNLOCK(ic); 1376 URTWN_LOCK(sc); 1377 callout_stop(&sc->sc_watchdog_ch); 1378 1379 if (ostate == IEEE80211_S_RUN) { 1380 /* Turn link LED off. */ 1381 urtwn_set_led(sc, URTWN_LED_LINK, 0); 1382 1383 /* Set media status to 'No Link'. */ 1384 reg = urtwn_read_4(sc, R92C_CR); 1385 reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_NOLINK); 1386 urtwn_write_4(sc, R92C_CR, reg); 1387 1388 /* Stop Rx of data frames. */ 1389 urtwn_write_2(sc, R92C_RXFLTMAP2, 0); 1390 1391 /* Rest TSF. */ 1392 urtwn_write_1(sc, R92C_DUAL_TSF_RST, 0x03); 1393 1394 /* Disable TSF synchronization. */ 1395 urtwn_write_1(sc, R92C_BCN_CTRL, 1396 urtwn_read_1(sc, R92C_BCN_CTRL) | 1397 R92C_BCN_CTRL_DIS_TSF_UDT0); 1398 1399 /* Reset EDCA parameters. */ 1400 urtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002f3217); 1401 urtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005e4317); 1402 urtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x00105320); 1403 urtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a444); 1404 } 1405 1406 switch (nstate) { 1407 case IEEE80211_S_INIT: 1408 /* Turn link LED off. */ 1409 urtwn_set_led(sc, URTWN_LED_LINK, 0); 1410 break; 1411 case IEEE80211_S_SCAN: 1412 if (ostate != IEEE80211_S_SCAN) { 1413 /* Allow Rx from any BSSID. */ 1414 urtwn_write_4(sc, R92C_RCR, 1415 urtwn_read_4(sc, R92C_RCR) & 1416 ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN)); 1417 1418 /* Set gain for scanning. */ 1419 reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0)); 1420 reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20); 1421 urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg); 1422 1423 reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1)); 1424 reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20); 1425 urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg); 1426 } 1427 1428 /* Make link LED blink during scan. */ 1429 urtwn_set_led(sc, URTWN_LED_LINK, !sc->ledlink); 1430 1431 /* Pause AC Tx queues. */ 1432 urtwn_write_1(sc, R92C_TXPAUSE, 1433 urtwn_read_1(sc, R92C_TXPAUSE) | 0x0f); 1434 1435 urtwn_set_chan(sc, ic->ic_curchan, NULL); 1436 break; 1437 case IEEE80211_S_AUTH: 1438 /* Set initial gain under link. */ 1439 reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0)); 1440 reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32); 1441 urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg); 1442 1443 reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1)); 1444 reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32); 1445 urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg); 1446 1447 urtwn_set_chan(sc, ic->ic_curchan, NULL); 1448 break; 1449 case IEEE80211_S_RUN: 1450 if (vap->iv_opmode == IEEE80211_M_MONITOR) { 1451 /* Enable Rx of data frames. */ 1452 urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff); 1453 1454 /* Turn link LED on. */ 1455 urtwn_set_led(sc, URTWN_LED_LINK, 1); 1456 break; 1457 } 1458 1459 ni = ieee80211_ref_node(vap->iv_bss); 1460 /* Set media status to 'Associated'. */ 1461 reg = urtwn_read_4(sc, R92C_CR); 1462 reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_INFRA); 1463 urtwn_write_4(sc, R92C_CR, reg); 1464 1465 /* Set BSSID. */ 1466 urtwn_write_4(sc, R92C_BSSID + 0, LE_READ_4(&ni->ni_bssid[0])); 1467 urtwn_write_4(sc, R92C_BSSID + 4, LE_READ_2(&ni->ni_bssid[4])); 1468 1469 if (ic->ic_curmode == IEEE80211_MODE_11B) 1470 urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 0); 1471 else /* 802.11b/g */ 1472 urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 3); 1473 1474 /* Enable Rx of data frames. */ 1475 urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff); 1476 1477 /* Flush all AC queues. */ 1478 urtwn_write_1(sc, R92C_TXPAUSE, 0); 1479 1480 /* Set beacon interval. */ 1481 urtwn_write_2(sc, R92C_BCN_INTERVAL, ni->ni_intval); 1482 1483 /* Allow Rx from our BSSID only. */ 1484 urtwn_write_4(sc, R92C_RCR, 1485 urtwn_read_4(sc, R92C_RCR) | 1486 R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN); 1487 1488 /* Enable TSF synchronization. */ 1489 urtwn_tsf_sync_enable(sc); 1490 1491 urtwn_write_1(sc, R92C_SIFS_CCK + 1, 10); 1492 urtwn_write_1(sc, R92C_SIFS_OFDM + 1, 10); 1493 urtwn_write_1(sc, R92C_SPEC_SIFS + 1, 10); 1494 urtwn_write_1(sc, R92C_MAC_SPEC_SIFS + 1, 10); 1495 urtwn_write_1(sc, R92C_R2T_SIFS + 1, 10); 1496 urtwn_write_1(sc, R92C_T2T_SIFS + 1, 10); 1497 1498 /* Intialize rate adaptation. */ 1499 urtwn_ra_init(sc); 1500 /* Turn link LED on. */ 1501 urtwn_set_led(sc, URTWN_LED_LINK, 1); 1502 1503 sc->avg_pwdb = -1; /* Reset average RSSI. */ 1504 /* Reset temperature calibration state machine. */ 1505 sc->thcal_state = 0; 1506 sc->thcal_lctemp = 0; 1507 ieee80211_free_node(ni); 1508 break; 1509 default: 1510 break; 1511 } 1512 URTWN_UNLOCK(sc); 1513 IEEE80211_LOCK(ic); 1514 return(uvp->newstate(vap, nstate, arg)); 1515} 1516 1517static void 1518urtwn_watchdog(void *arg) 1519{ 1520 struct urtwn_softc *sc = arg; 1521 struct ifnet *ifp = sc->sc_ifp; 1522 1523 if (sc->sc_txtimer > 0) { 1524 if (--sc->sc_txtimer == 0) { 1525 device_printf(sc->sc_dev, "device timeout\n"); 1526 ifp->if_oerrors++; 1527 return; 1528 } 1529 callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc); 1530 } 1531} 1532 1533static void 1534urtwn_update_avgrssi(struct urtwn_softc *sc, int rate, int8_t rssi) 1535{ 1536 int pwdb; 1537 1538 /* Convert antenna signal to percentage. */ 1539 if (rssi <= -100 || rssi >= 20) 1540 pwdb = 0; 1541 else if (rssi >= 0) 1542 pwdb = 100; 1543 else 1544 pwdb = 100 + rssi; 1545 if (rate <= 3) { 1546 /* CCK gain is smaller than OFDM/MCS gain. */ 1547 pwdb += 6; 1548 if (pwdb > 100) 1549 pwdb = 100; 1550 if (pwdb <= 14) 1551 pwdb -= 4; 1552 else if (pwdb <= 26) 1553 pwdb -= 8; 1554 else if (pwdb <= 34) 1555 pwdb -= 6; 1556 else if (pwdb <= 42) 1557 pwdb -= 2; 1558 } 1559 if (sc->avg_pwdb == -1) /* Init. */ 1560 sc->avg_pwdb = pwdb; 1561 else if (sc->avg_pwdb < pwdb) 1562 sc->avg_pwdb = ((sc->avg_pwdb * 19 + pwdb) / 20) + 1; 1563 else 1564 sc->avg_pwdb = ((sc->avg_pwdb * 19 + pwdb) / 20); 1565 DPRINTFN(4, "PWDB=%d EMA=%d\n", pwdb, sc->avg_pwdb); 1566} 1567 1568static int8_t 1569urtwn_get_rssi(struct urtwn_softc *sc, int rate, void *physt) 1570{ 1571 static const int8_t cckoff[] = { 16, -12, -26, -46 }; 1572 struct r92c_rx_phystat *phy; 1573 struct r92c_rx_cck *cck; 1574 uint8_t rpt; 1575 int8_t rssi; 1576 1577 if (rate <= 3) { 1578 cck = (struct r92c_rx_cck *)physt; 1579 if (sc->sc_flags & URTWN_FLAG_CCK_HIPWR) { 1580 rpt = (cck->agc_rpt >> 5) & 0x3; 1581 rssi = (cck->agc_rpt & 0x1f) << 1; 1582 } else { 1583 rpt = (cck->agc_rpt >> 6) & 0x3; 1584 rssi = cck->agc_rpt & 0x3e; 1585 } 1586 rssi = cckoff[rpt] - rssi; 1587 } else { /* OFDM/HT. */ 1588 phy = (struct r92c_rx_phystat *)physt; 1589 rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 110; 1590 } 1591 return (rssi); 1592} 1593 1594static int 1595urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni, 1596 struct mbuf *m0, struct urtwn_data *data) 1597{ 1598 struct ifnet *ifp = sc->sc_ifp; 1599 struct ieee80211_frame *wh; 1600 struct ieee80211_key *k; 1601 struct ieee80211com *ic = ifp->if_l2com; 1602 struct ieee80211vap *vap = ni->ni_vap; 1603 struct usb_xfer *xfer; 1604 struct r92c_tx_desc *txd; 1605 uint8_t raid, type; 1606 uint16_t sum; 1607 int i, hasqos, xferlen; 1608 struct usb_xfer *urtwn_pipes[4] = { 1609 sc->sc_xfer[URTWN_BULK_TX_BE], 1610 sc->sc_xfer[URTWN_BULK_TX_BK], 1611 sc->sc_xfer[URTWN_BULK_TX_VI], 1612 sc->sc_xfer[URTWN_BULK_TX_VO] 1613 }; 1614 1615 URTWN_ASSERT_LOCKED(sc); 1616 1617 /* 1618 * Software crypto. 1619 */ 1620 wh = mtod(m0, struct ieee80211_frame *); 1621 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 1622 k = ieee80211_crypto_encap(ni, m0); 1623 if (k == NULL) { 1624 device_printf(sc->sc_dev, 1625 "ieee80211_crypto_encap returns NULL.\n"); 1626 /* XXX we don't expect the fragmented frames */ 1627 m_freem(m0); 1628 return (ENOBUFS); 1629 } 1630 1631 /* in case packet header moved, reset pointer */ 1632 wh = mtod(m0, struct ieee80211_frame *); 1633 } 1634 1635 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) { 1636 case IEEE80211_FC0_TYPE_CTL: 1637 case IEEE80211_FC0_TYPE_MGT: 1638 xfer = sc->sc_xfer[URTWN_BULK_TX_VO]; 1639 break; 1640 default: 1641 KASSERT(M_WME_GETAC(m0) < 4, 1642 ("unsupported WME pipe %d", M_WME_GETAC(m0))); 1643 xfer = urtwn_pipes[M_WME_GETAC(m0)]; 1644 break; 1645 } 1646 1647 hasqos = 0; 1648 1649 /* Fill Tx descriptor. */ 1650 txd = (struct r92c_tx_desc *)data->buf; 1651 memset(txd, 0, sizeof(*txd)); 1652 1653 txd->txdw0 |= htole32( 1654 SM(R92C_TXDW0_PKTLEN, m0->m_pkthdr.len) | 1655 SM(R92C_TXDW0_OFFSET, sizeof(*txd)) | 1656 R92C_TXDW0_OWN | R92C_TXDW0_FSG | R92C_TXDW0_LSG); 1657 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) 1658 txd->txdw0 |= htole32(R92C_TXDW0_BMCAST); 1659 1660 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 1661 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 1662 type == IEEE80211_FC0_TYPE_DATA) { 1663 if (ic->ic_curmode == IEEE80211_MODE_11B) 1664 raid = R92C_RAID_11B; 1665 else 1666 raid = R92C_RAID_11BG; 1667 txd->txdw1 |= htole32( 1668 SM(R92C_TXDW1_MACID, URTWN_MACID_BSS) | 1669 SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) | 1670 SM(R92C_TXDW1_RAID, raid) | 1671 R92C_TXDW1_AGGBK); 1672 1673 if (ic->ic_flags & IEEE80211_F_USEPROT) { 1674 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { 1675 txd->txdw4 |= htole32(R92C_TXDW4_CTS2SELF | 1676 R92C_TXDW4_HWRTSEN); 1677 } else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) { 1678 txd->txdw4 |= htole32(R92C_TXDW4_RTSEN | 1679 R92C_TXDW4_HWRTSEN); 1680 } 1681 } 1682 /* Send RTS at OFDM24. */ 1683 txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, 8)); 1684 txd->txdw5 |= htole32(0x0001ff00); 1685 /* Send data at OFDM54. */ 1686 txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11)); 1687 } else { 1688 txd->txdw1 |= htole32( 1689 SM(R92C_TXDW1_MACID, 0) | 1690 SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT) | 1691 SM(R92C_TXDW1_RAID, R92C_RAID_11B)); 1692 1693 /* Force CCK1. */ 1694 txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE); 1695 txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 0)); 1696 } 1697 /* Set sequence number (already little endian). */ 1698 txd->txdseq |= *(uint16_t *)wh->i_seq; 1699 1700 if (!hasqos) { 1701 /* Use HW sequence numbering for non-QoS frames. */ 1702 txd->txdw4 |= htole32(R92C_TXDW4_HWSEQ); 1703 txd->txdseq |= htole16(0x8000); 1704 } else 1705 txd->txdw4 |= htole32(R92C_TXDW4_QOS); 1706 1707 /* Compute Tx descriptor checksum. */ 1708 sum = 0; 1709 for (i = 0; i < sizeof(*txd) / 2; i++) 1710 sum ^= ((uint16_t *)txd)[i]; 1711 txd->txdsum = sum; /* NB: already little endian. */ 1712 1713 if (ieee80211_radiotap_active_vap(vap)) { 1714 struct urtwn_tx_radiotap_header *tap = &sc->sc_txtap; 1715 1716 tap->wt_flags = 0; 1717 tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); 1718 tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); 1719 ieee80211_radiotap_tx(vap, m0); 1720 } 1721 1722 xferlen = sizeof(*txd) + m0->m_pkthdr.len; 1723 m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&txd[1]); 1724 1725 data->buflen = xferlen; 1726 data->ni = ni; 1727 data->m = m0; 1728 1729 STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next); 1730 usbd_transfer_start(xfer); 1731 return (0); 1732} 1733 1734static void 1735urtwn_start(struct ifnet *ifp) 1736{ 1737 struct urtwn_softc *sc = ifp->if_softc; 1738 1739 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 1740 return; 1741 URTWN_LOCK(sc); 1742 urtwn_start_locked(ifp, sc); 1743 URTWN_UNLOCK(sc); 1744} 1745 1746static void 1747urtwn_start_locked(struct ifnet *ifp, struct urtwn_softc *sc) 1748{ 1749 struct ieee80211_node *ni; 1750 struct mbuf *m; 1751 struct urtwn_data *bf; 1752 1753 URTWN_ASSERT_LOCKED(sc); 1754 for (;;) { 1755 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 1756 if (m == NULL) 1757 break; 1758 bf = urtwn_getbuf(sc); 1759 if (bf == NULL) { 1760 IFQ_DRV_PREPEND(&ifp->if_snd, m); 1761 break; 1762 } 1763 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 1764 m->m_pkthdr.rcvif = NULL; 1765 1766 if (urtwn_tx_start(sc, ni, m, bf) != 0) { 1767 ifp->if_oerrors++; 1768 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); 1769 ieee80211_free_node(ni); 1770 break; 1771 } 1772 1773 sc->sc_txtimer = 5; 1774 callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc); 1775 } 1776} 1777 1778static int 1779urtwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1780{ 1781 struct urtwn_softc *sc = ifp->if_softc; 1782 struct ieee80211com *ic = ifp->if_l2com; 1783 struct ifreq *ifr = (struct ifreq *) data; 1784 int error = 0, startall = 0; 1785 1786 URTWN_LOCK(sc); 1787 error = (sc->sc_flags & URTWN_DETACHED) ? ENXIO : 0; 1788 URTWN_UNLOCK(sc); 1789 if (error != 0) 1790 return (error); 1791 1792 switch (cmd) { 1793 case SIOCSIFFLAGS: 1794 if (ifp->if_flags & IFF_UP) { 1795 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { 1796 urtwn_init(ifp->if_softc); 1797 startall = 1; 1798 } 1799 } else { 1800 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 1801 urtwn_stop(ifp); 1802 } 1803 if (startall) 1804 ieee80211_start_all(ic); 1805 break; 1806 case SIOCGIFMEDIA: 1807 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1808 break; 1809 case SIOCGIFADDR: 1810 error = ether_ioctl(ifp, cmd, data); 1811 break; 1812 default: 1813 error = EINVAL; 1814 break; 1815 } 1816 return (error); 1817} 1818 1819static int 1820urtwn_alloc_list(struct urtwn_softc *sc, struct urtwn_data data[], 1821 int ndata, int maxsz) 1822{ 1823 int i, error; 1824 1825 for (i = 0; i < ndata; i++) { 1826 struct urtwn_data *dp = &data[i]; 1827 dp->sc = sc; 1828 dp->m = NULL; 1829 dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT); 1830 if (dp->buf == NULL) { 1831 device_printf(sc->sc_dev, 1832 "could not allocate buffer\n"); 1833 error = ENOMEM; 1834 goto fail; 1835 } 1836 dp->ni = NULL; 1837 } 1838 1839 return (0); 1840fail: 1841 urtwn_free_list(sc, data, ndata); 1842 return (error); 1843} 1844 1845static int 1846urtwn_alloc_rx_list(struct urtwn_softc *sc) 1847{ 1848 int error, i; 1849 1850 error = urtwn_alloc_list(sc, sc->sc_rx, URTWN_RX_LIST_COUNT, 1851 URTWN_RXBUFSZ); 1852 if (error != 0) 1853 return (error); 1854 1855 STAILQ_INIT(&sc->sc_rx_active); 1856 STAILQ_INIT(&sc->sc_rx_inactive); 1857 1858 for (i = 0; i < URTWN_RX_LIST_COUNT; i++) 1859 STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next); 1860 1861 return (0); 1862} 1863 1864static int 1865urtwn_alloc_tx_list(struct urtwn_softc *sc) 1866{ 1867 int error, i; 1868 1869 error = urtwn_alloc_list(sc, sc->sc_tx, URTWN_TX_LIST_COUNT, 1870 URTWN_TXBUFSZ); 1871 if (error != 0) 1872 return (error); 1873 1874 STAILQ_INIT(&sc->sc_tx_active); 1875 STAILQ_INIT(&sc->sc_tx_inactive); 1876 STAILQ_INIT(&sc->sc_tx_pending); 1877 1878 for (i = 0; i < URTWN_TX_LIST_COUNT; i++) 1879 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i], next); 1880 1881 return (0); 1882} 1883 1884static int 1885urtwn_power_on(struct urtwn_softc *sc) 1886{ 1887 uint32_t reg; 1888 int ntries; 1889 1890 /* Wait for autoload done bit. */ 1891 for (ntries = 0; ntries < 1000; ntries++) { 1892 if (urtwn_read_1(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_PFM_ALDN) 1893 break; 1894 DELAY(5); 1895 } 1896 if (ntries == 1000) { 1897 device_printf(sc->sc_dev, 1898 "timeout waiting for chip autoload\n"); 1899 return (ETIMEDOUT); 1900 } 1901 1902 /* Unlock ISO/CLK/Power control register. */ 1903 urtwn_write_1(sc, R92C_RSV_CTRL, 0); 1904 /* Move SPS into PWM mode. */ 1905 urtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b); 1906 DELAY(100); 1907 1908 reg = urtwn_read_1(sc, R92C_LDOV12D_CTRL); 1909 if (!(reg & R92C_LDOV12D_CTRL_LDV12_EN)) { 1910 urtwn_write_1(sc, R92C_LDOV12D_CTRL, 1911 reg | R92C_LDOV12D_CTRL_LDV12_EN); 1912 DELAY(100); 1913 urtwn_write_1(sc, R92C_SYS_ISO_CTRL, 1914 urtwn_read_1(sc, R92C_SYS_ISO_CTRL) & 1915 ~R92C_SYS_ISO_CTRL_MD2PP); 1916 } 1917 1918 /* Auto enable WLAN. */ 1919 urtwn_write_2(sc, R92C_APS_FSMCO, 1920 urtwn_read_2(sc, R92C_APS_FSMCO) | R92C_APS_FSMCO_APFM_ONMAC); 1921 for (ntries = 0; ntries < 1000; ntries++) { 1922 if (!(urtwn_read_2(sc, R92C_APS_FSMCO) & 1923 R92C_APS_FSMCO_APFM_ONMAC)) 1924 break; 1925 DELAY(5); 1926 } 1927 if (ntries == 1000) { 1928 device_printf(sc->sc_dev, 1929 "timeout waiting for MAC auto ON\n"); 1930 return (ETIMEDOUT); 1931 } 1932 1933 /* Enable radio, GPIO and LED functions. */ 1934 urtwn_write_2(sc, R92C_APS_FSMCO, 1935 R92C_APS_FSMCO_AFSM_HSUS | 1936 R92C_APS_FSMCO_PDN_EN | 1937 R92C_APS_FSMCO_PFM_ALDN); 1938 /* Release RF digital isolation. */ 1939 urtwn_write_2(sc, R92C_SYS_ISO_CTRL, 1940 urtwn_read_2(sc, R92C_SYS_ISO_CTRL) & ~R92C_SYS_ISO_CTRL_DIOR); 1941 1942 /* Initialize MAC. */ 1943 urtwn_write_1(sc, R92C_APSD_CTRL, 1944 urtwn_read_1(sc, R92C_APSD_CTRL) & ~R92C_APSD_CTRL_OFF); 1945 for (ntries = 0; ntries < 200; ntries++) { 1946 if (!(urtwn_read_1(sc, R92C_APSD_CTRL) & 1947 R92C_APSD_CTRL_OFF_STATUS)) 1948 break; 1949 DELAY(5); 1950 } 1951 if (ntries == 200) { 1952 device_printf(sc->sc_dev, 1953 "timeout waiting for MAC initialization\n"); 1954 return (ETIMEDOUT); 1955 } 1956 1957 /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */ 1958 reg = urtwn_read_2(sc, R92C_CR); 1959 reg |= R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN | 1960 R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN | 1961 R92C_CR_SCHEDULE_EN | R92C_CR_MACTXEN | R92C_CR_MACRXEN | 1962 R92C_CR_ENSEC; 1963 urtwn_write_2(sc, R92C_CR, reg); 1964 1965 urtwn_write_1(sc, 0xfe10, 0x19); 1966 return (0); 1967} 1968 1969static int 1970urtwn_llt_init(struct urtwn_softc *sc) 1971{ 1972 int i, error; 1973 1974 /* Reserve pages [0; R92C_TX_PAGE_COUNT]. */ 1975 for (i = 0; i < R92C_TX_PAGE_COUNT; i++) { 1976 if ((error = urtwn_llt_write(sc, i, i + 1)) != 0) 1977 return (error); 1978 } 1979 /* NB: 0xff indicates end-of-list. */ 1980 if ((error = urtwn_llt_write(sc, i, 0xff)) != 0) 1981 return (error); 1982 /* 1983 * Use pages [R92C_TX_PAGE_COUNT + 1; R92C_TXPKTBUF_COUNT - 1] 1984 * as ring buffer. 1985 */ 1986 for (++i; i < R92C_TXPKTBUF_COUNT - 1; i++) { 1987 if ((error = urtwn_llt_write(sc, i, i + 1)) != 0) 1988 return (error); 1989 } 1990 /* Make the last page point to the beginning of the ring buffer. */ 1991 error = urtwn_llt_write(sc, i, R92C_TX_PAGE_COUNT + 1); 1992 return (error); 1993} 1994 1995static void 1996urtwn_fw_reset(struct urtwn_softc *sc) 1997{ 1998 uint16_t reg; 1999 int ntries; 2000 2001 /* Tell 8051 to reset itself. */ 2002 urtwn_write_1(sc, R92C_HMETFR + 3, 0x20); 2003 2004 /* Wait until 8051 resets by itself. */ 2005 for (ntries = 0; ntries < 100; ntries++) { 2006 reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN); 2007 if (!(reg & R92C_SYS_FUNC_EN_CPUEN)) 2008 return; 2009 DELAY(50); 2010 } 2011 /* Force 8051 reset. */ 2012 urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN); 2013} 2014 2015static int 2016urtwn_fw_loadpage(struct urtwn_softc *sc, int page, const uint8_t *buf, int len) 2017{ 2018 uint32_t reg; 2019 int off, mlen, error = 0; 2020 2021 reg = urtwn_read_4(sc, R92C_MCUFWDL); 2022 reg = RW(reg, R92C_MCUFWDL_PAGE, page); 2023 urtwn_write_4(sc, R92C_MCUFWDL, reg); 2024 2025 off = R92C_FW_START_ADDR; 2026 while (len > 0) { 2027 if (len > 196) 2028 mlen = 196; 2029 else if (len > 4) 2030 mlen = 4; 2031 else 2032 mlen = 1; 2033 /* XXX fix this deconst */ 2034 error = urtwn_write_region_1(sc, off, 2035 __DECONST(uint8_t *, buf), mlen); 2036 if (error != 0) 2037 break; 2038 off += mlen; 2039 buf += mlen; 2040 len -= mlen; 2041 } 2042 return (error); 2043} 2044 2045static int 2046urtwn_load_firmware(struct urtwn_softc *sc) 2047{ 2048 const struct firmware *fw; 2049 const struct r92c_fw_hdr *hdr; 2050 const char *imagename; 2051 const u_char *ptr; 2052 size_t len; 2053 uint32_t reg; 2054 int mlen, ntries, page, error; 2055 2056 /* Read firmware image from the filesystem. */ 2057 if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) == 2058 URTWN_CHIP_UMC_A_CUT) 2059 imagename = "urtwn-rtl8192cfwU"; 2060 else 2061 imagename = "urtwn-rtl8192cfwT"; 2062 2063 fw = firmware_get(imagename); 2064 if (fw == NULL) { 2065 device_printf(sc->sc_dev, 2066 "failed loadfirmware of file %s\n", imagename); 2067 return (ENOENT); 2068 } 2069 2070 len = fw->datasize; 2071 2072 if (len < sizeof(*hdr)) { 2073 device_printf(sc->sc_dev, "firmware too short\n"); 2074 error = EINVAL; 2075 goto fail; 2076 } 2077 ptr = fw->data; 2078 hdr = (const struct r92c_fw_hdr *)ptr; 2079 /* Check if there is a valid FW header and skip it. */ 2080 if ((le16toh(hdr->signature) >> 4) == 0x88c || 2081 (le16toh(hdr->signature) >> 4) == 0x92c) { 2082 DPRINTF("FW V%d.%d %02d-%02d %02d:%02d\n", 2083 le16toh(hdr->version), le16toh(hdr->subversion), 2084 hdr->month, hdr->date, hdr->hour, hdr->minute); 2085 ptr += sizeof(*hdr); 2086 len -= sizeof(*hdr); 2087 } 2088 2089 if (urtwn_read_1(sc, R92C_MCUFWDL) & 0x80) { 2090 urtwn_fw_reset(sc); 2091 urtwn_write_1(sc, R92C_MCUFWDL, 0); 2092 } 2093 urtwn_write_2(sc, R92C_SYS_FUNC_EN, 2094 urtwn_read_2(sc, R92C_SYS_FUNC_EN) | 2095 R92C_SYS_FUNC_EN_CPUEN); 2096 urtwn_write_1(sc, R92C_MCUFWDL, 2097 urtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_EN); 2098 urtwn_write_1(sc, R92C_MCUFWDL + 2, 2099 urtwn_read_1(sc, R92C_MCUFWDL + 2) & ~0x08); 2100 2101 for (page = 0; len > 0; page++) { 2102 mlen = min(len, R92C_FW_PAGE_SIZE); 2103 error = urtwn_fw_loadpage(sc, page, ptr, mlen); 2104 if (error != 0) { 2105 device_printf(sc->sc_dev, 2106 "could not load firmware page\n"); 2107 goto fail; 2108 } 2109 ptr += mlen; 2110 len -= mlen; 2111 } 2112 urtwn_write_1(sc, R92C_MCUFWDL, 2113 urtwn_read_1(sc, R92C_MCUFWDL) & ~R92C_MCUFWDL_EN); 2114 urtwn_write_1(sc, R92C_MCUFWDL + 1, 0); 2115 2116 /* Wait for checksum report. */ 2117 for (ntries = 0; ntries < 1000; ntries++) { 2118 if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_CHKSUM_RPT) 2119 break; 2120 DELAY(5); 2121 } 2122 if (ntries == 1000) { 2123 device_printf(sc->sc_dev, 2124 "timeout waiting for checksum report\n"); 2125 error = ETIMEDOUT; 2126 goto fail; 2127 } 2128 2129 reg = urtwn_read_4(sc, R92C_MCUFWDL); 2130 reg = (reg & ~R92C_MCUFWDL_WINTINI_RDY) | R92C_MCUFWDL_RDY; 2131 urtwn_write_4(sc, R92C_MCUFWDL, reg); 2132 /* Wait for firmware readiness. */ 2133 for (ntries = 0; ntries < 1000; ntries++) { 2134 if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_WINTINI_RDY) 2135 break; 2136 DELAY(5); 2137 } 2138 if (ntries == 1000) { 2139 device_printf(sc->sc_dev, 2140 "timeout waiting for firmware readiness\n"); 2141 error = ETIMEDOUT; 2142 goto fail; 2143 } 2144fail: 2145 firmware_put(fw, FIRMWARE_UNLOAD); 2146 return (error); 2147} 2148 2149static int 2150urtwn_dma_init(struct urtwn_softc *sc) 2151{ 2152 int hashq, hasnq, haslq, nqueues, nqpages, nrempages; 2153 uint32_t reg; 2154 int error; 2155 2156 /* Initialize LLT table. */ 2157 error = urtwn_llt_init(sc); 2158 if (error != 0) 2159 return (error); 2160 2161 /* Get Tx queues to USB endpoints mapping. */ 2162 hashq = hasnq = haslq = 0; 2163 reg = urtwn_read_2(sc, R92C_USB_EP + 1); 2164 DPRINTFN(2, "USB endpoints mapping 0x%x\n", reg); 2165 if (MS(reg, R92C_USB_EP_HQ) != 0) 2166 hashq = 1; 2167 if (MS(reg, R92C_USB_EP_NQ) != 0) 2168 hasnq = 1; 2169 if (MS(reg, R92C_USB_EP_LQ) != 0) 2170 haslq = 1; 2171 nqueues = hashq + hasnq + haslq; 2172 if (nqueues == 0) 2173 return (EIO); 2174 /* Get the number of pages for each queue. */ 2175 nqpages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) / nqueues; 2176 /* The remaining pages are assigned to the high priority queue. */ 2177 nrempages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) % nqueues; 2178 2179 /* Set number of pages for normal priority queue. */ 2180 urtwn_write_1(sc, R92C_RQPN_NPQ, hasnq ? nqpages : 0); 2181 urtwn_write_4(sc, R92C_RQPN, 2182 /* Set number of pages for public queue. */ 2183 SM(R92C_RQPN_PUBQ, R92C_PUBQ_NPAGES) | 2184 /* Set number of pages for high priority queue. */ 2185 SM(R92C_RQPN_HPQ, hashq ? nqpages + nrempages : 0) | 2186 /* Set number of pages for low priority queue. */ 2187 SM(R92C_RQPN_LPQ, haslq ? nqpages : 0) | 2188 /* Load values. */ 2189 R92C_RQPN_LD); 2190 2191 urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R92C_TX_PAGE_BOUNDARY); 2192 urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R92C_TX_PAGE_BOUNDARY); 2193 urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, R92C_TX_PAGE_BOUNDARY); 2194 urtwn_write_1(sc, R92C_TRXFF_BNDY, R92C_TX_PAGE_BOUNDARY); 2195 urtwn_write_1(sc, R92C_TDECTRL + 1, R92C_TX_PAGE_BOUNDARY); 2196 2197 /* Set queue to USB pipe mapping. */ 2198 reg = urtwn_read_2(sc, R92C_TRXDMA_CTRL); 2199 reg &= ~R92C_TRXDMA_CTRL_QMAP_M; 2200 if (nqueues == 1) { 2201 if (hashq) 2202 reg |= R92C_TRXDMA_CTRL_QMAP_HQ; 2203 else if (hasnq) 2204 reg |= R92C_TRXDMA_CTRL_QMAP_NQ; 2205 else 2206 reg |= R92C_TRXDMA_CTRL_QMAP_LQ; 2207 } else if (nqueues == 2) { 2208 /* All 2-endpoints configs have a high priority queue. */ 2209 if (!hashq) 2210 return (EIO); 2211 if (hasnq) 2212 reg |= R92C_TRXDMA_CTRL_QMAP_HQ_NQ; 2213 else 2214 reg |= R92C_TRXDMA_CTRL_QMAP_HQ_LQ; 2215 } else 2216 reg |= R92C_TRXDMA_CTRL_QMAP_3EP; 2217 urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg); 2218 2219 /* Set Tx/Rx transfer page boundary. */ 2220 urtwn_write_2(sc, R92C_TRXFF_BNDY + 2, 0x27ff); 2221 2222 /* Set Tx/Rx transfer page size. */ 2223 urtwn_write_1(sc, R92C_PBP, 2224 SM(R92C_PBP_PSRX, R92C_PBP_128) | 2225 SM(R92C_PBP_PSTX, R92C_PBP_128)); 2226 return (0); 2227} 2228 2229static void 2230urtwn_mac_init(struct urtwn_softc *sc) 2231{ 2232 int i; 2233 2234 /* Write MAC initialization values. */ 2235 for (i = 0; i < nitems(rtl8192cu_mac); i++) 2236 urtwn_write_1(sc, rtl8192cu_mac[i].reg, rtl8192cu_mac[i].val); 2237} 2238 2239static void 2240urtwn_bb_init(struct urtwn_softc *sc) 2241{ 2242 const struct urtwn_bb_prog *prog; 2243 uint32_t reg; 2244 int i; 2245 2246 /* Enable BB and RF. */ 2247 urtwn_write_2(sc, R92C_SYS_FUNC_EN, 2248 urtwn_read_2(sc, R92C_SYS_FUNC_EN) | 2249 R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST | 2250 R92C_SYS_FUNC_EN_DIO_RF); 2251 2252 urtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83); 2253 2254 urtwn_write_1(sc, R92C_RF_CTRL, 2255 R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB); 2256 urtwn_write_1(sc, R92C_SYS_FUNC_EN, 2257 R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD | 2258 R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_BBRSTB); 2259 2260 urtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f); 2261 urtwn_write_1(sc, 0x15, 0xe9); 2262 urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80); 2263 2264 /* Select BB programming based on board type. */ 2265 if (!(sc->chip & URTWN_CHIP_92C)) { 2266 if (sc->board_type == R92C_BOARD_TYPE_MINICARD) 2267 prog = &rtl8188ce_bb_prog; 2268 else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA) 2269 prog = &rtl8188ru_bb_prog; 2270 else 2271 prog = &rtl8188cu_bb_prog; 2272 } else { 2273 if (sc->board_type == R92C_BOARD_TYPE_MINICARD) 2274 prog = &rtl8192ce_bb_prog; 2275 else 2276 prog = &rtl8192cu_bb_prog; 2277 } 2278 /* Write BB initialization values. */ 2279 for (i = 0; i < prog->count; i++) { 2280 urtwn_bb_write(sc, prog->regs[i], prog->vals[i]); 2281 DELAY(1); 2282 } 2283 2284 if (sc->chip & URTWN_CHIP_92C_1T2R) { 2285 /* 8192C 1T only configuration. */ 2286 reg = urtwn_bb_read(sc, R92C_FPGA0_TXINFO); 2287 reg = (reg & ~0x00000003) | 0x2; 2288 urtwn_bb_write(sc, R92C_FPGA0_TXINFO, reg); 2289 2290 reg = urtwn_bb_read(sc, R92C_FPGA1_TXINFO); 2291 reg = (reg & ~0x00300033) | 0x00200022; 2292 urtwn_bb_write(sc, R92C_FPGA1_TXINFO, reg); 2293 2294 reg = urtwn_bb_read(sc, R92C_CCK0_AFESETTING); 2295 reg = (reg & ~0xff000000) | 0x45 << 24; 2296 urtwn_bb_write(sc, R92C_CCK0_AFESETTING, reg); 2297 2298 reg = urtwn_bb_read(sc, R92C_OFDM0_TRXPATHENA); 2299 reg = (reg & ~0x000000ff) | 0x23; 2300 urtwn_bb_write(sc, R92C_OFDM0_TRXPATHENA, reg); 2301 2302 reg = urtwn_bb_read(sc, R92C_OFDM0_AGCPARAM1); 2303 reg = (reg & ~0x00000030) | 1 << 4; 2304 urtwn_bb_write(sc, R92C_OFDM0_AGCPARAM1, reg); 2305 2306 reg = urtwn_bb_read(sc, 0xe74); 2307 reg = (reg & ~0x0c000000) | 2 << 26; 2308 urtwn_bb_write(sc, 0xe74, reg); 2309 reg = urtwn_bb_read(sc, 0xe78); 2310 reg = (reg & ~0x0c000000) | 2 << 26; 2311 urtwn_bb_write(sc, 0xe78, reg); 2312 reg = urtwn_bb_read(sc, 0xe7c); 2313 reg = (reg & ~0x0c000000) | 2 << 26; 2314 urtwn_bb_write(sc, 0xe7c, reg); 2315 reg = urtwn_bb_read(sc, 0xe80); 2316 reg = (reg & ~0x0c000000) | 2 << 26; 2317 urtwn_bb_write(sc, 0xe80, reg); 2318 reg = urtwn_bb_read(sc, 0xe88); 2319 reg = (reg & ~0x0c000000) | 2 << 26; 2320 urtwn_bb_write(sc, 0xe88, reg); 2321 } 2322 2323 /* Write AGC values. */ 2324 for (i = 0; i < prog->agccount; i++) { 2325 urtwn_bb_write(sc, R92C_OFDM0_AGCRSSITABLE, 2326 prog->agcvals[i]); 2327 DELAY(1); 2328 } 2329 2330 if (urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) & 2331 R92C_HSSI_PARAM2_CCK_HIPWR) 2332 sc->sc_flags |= URTWN_FLAG_CCK_HIPWR; 2333} 2334 2335void 2336urtwn_rf_init(struct urtwn_softc *sc) 2337{ 2338 const struct urtwn_rf_prog *prog; 2339 uint32_t reg, type; 2340 int i, j, idx, off; 2341 2342 /* Select RF programming based on board type. */ 2343 if (!(sc->chip & URTWN_CHIP_92C)) { 2344 if (sc->board_type == R92C_BOARD_TYPE_MINICARD) 2345 prog = rtl8188ce_rf_prog; 2346 else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA) 2347 prog = rtl8188ru_rf_prog; 2348 else 2349 prog = rtl8188cu_rf_prog; 2350 } else 2351 prog = rtl8192ce_rf_prog; 2352 2353 for (i = 0; i < sc->nrxchains; i++) { 2354 /* Save RF_ENV control type. */ 2355 idx = i / 2; 2356 off = (i % 2) * 16; 2357 reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx)); 2358 type = (reg >> off) & 0x10; 2359 2360 /* Set RF_ENV enable. */ 2361 reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i)); 2362 reg |= 0x100000; 2363 urtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg); 2364 DELAY(1); 2365 /* Set RF_ENV output high. */ 2366 reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i)); 2367 reg |= 0x10; 2368 urtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg); 2369 DELAY(1); 2370 /* Set address and data lengths of RF registers. */ 2371 reg = urtwn_bb_read(sc, R92C_HSSI_PARAM2(i)); 2372 reg &= ~R92C_HSSI_PARAM2_ADDR_LENGTH; 2373 urtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg); 2374 DELAY(1); 2375 reg = urtwn_bb_read(sc, R92C_HSSI_PARAM2(i)); 2376 reg &= ~R92C_HSSI_PARAM2_DATA_LENGTH; 2377 urtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg); 2378 DELAY(1); 2379 2380 /* Write RF initialization values for this chain. */ 2381 for (j = 0; j < prog[i].count; j++) { 2382 if (prog[i].regs[j] >= 0xf9 && 2383 prog[i].regs[j] <= 0xfe) { 2384 /* 2385 * These are fake RF registers offsets that 2386 * indicate a delay is required. 2387 */ 2388 usb_pause_mtx(&sc->sc_mtx, 50); 2389 continue; 2390 } 2391 urtwn_rf_write(sc, i, prog[i].regs[j], 2392 prog[i].vals[j]); 2393 DELAY(1); 2394 } 2395 2396 /* Restore RF_ENV control type. */ 2397 reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx)); 2398 reg &= ~(0x10 << off) | (type << off); 2399 urtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(idx), reg); 2400 2401 /* Cache RF register CHNLBW. */ 2402 sc->rf_chnlbw[i] = urtwn_rf_read(sc, i, R92C_RF_CHNLBW); 2403 } 2404 2405 if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) == 2406 URTWN_CHIP_UMC_A_CUT) { 2407 urtwn_rf_write(sc, 0, R92C_RF_RX_G1, 0x30255); 2408 urtwn_rf_write(sc, 0, R92C_RF_RX_G2, 0x50a00); 2409 } 2410} 2411 2412static void 2413urtwn_cam_init(struct urtwn_softc *sc) 2414{ 2415 /* Invalidate all CAM entries. */ 2416 urtwn_write_4(sc, R92C_CAMCMD, 2417 R92C_CAMCMD_POLLING | R92C_CAMCMD_CLR); 2418} 2419 2420static void 2421urtwn_pa_bias_init(struct urtwn_softc *sc) 2422{ 2423 uint8_t reg; 2424 int i; 2425 2426 for (i = 0; i < sc->nrxchains; i++) { 2427 if (sc->pa_setting & (1 << i)) 2428 continue; 2429 urtwn_rf_write(sc, i, R92C_RF_IPA, 0x0f406); 2430 urtwn_rf_write(sc, i, R92C_RF_IPA, 0x4f406); 2431 urtwn_rf_write(sc, i, R92C_RF_IPA, 0x8f406); 2432 urtwn_rf_write(sc, i, R92C_RF_IPA, 0xcf406); 2433 } 2434 if (!(sc->pa_setting & 0x10)) { 2435 reg = urtwn_read_1(sc, 0x16); 2436 reg = (reg & ~0xf0) | 0x90; 2437 urtwn_write_1(sc, 0x16, reg); 2438 } 2439} 2440 2441static void 2442urtwn_rxfilter_init(struct urtwn_softc *sc) 2443{ 2444 /* Initialize Rx filter. */ 2445 /* TODO: use better filter for monitor mode. */ 2446 urtwn_write_4(sc, R92C_RCR, 2447 R92C_RCR_AAP | R92C_RCR_APM | R92C_RCR_AM | R92C_RCR_AB | 2448 R92C_RCR_APP_ICV | R92C_RCR_AMF | R92C_RCR_HTC_LOC_CTRL | 2449 R92C_RCR_APP_MIC | R92C_RCR_APP_PHYSTS); 2450 /* Accept all multicast frames. */ 2451 urtwn_write_4(sc, R92C_MAR + 0, 0xffffffff); 2452 urtwn_write_4(sc, R92C_MAR + 4, 0xffffffff); 2453 /* Accept all management frames. */ 2454 urtwn_write_2(sc, R92C_RXFLTMAP0, 0xffff); 2455 /* Reject all control frames. */ 2456 urtwn_write_2(sc, R92C_RXFLTMAP1, 0x0000); 2457 /* Accept all data frames. */ 2458 urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff); 2459} 2460 2461static void 2462urtwn_edca_init(struct urtwn_softc *sc) 2463{ 2464 urtwn_write_2(sc, R92C_SPEC_SIFS, 0x100a); 2465 urtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x100a); 2466 urtwn_write_2(sc, R92C_SIFS_CCK, 0x100a); 2467 urtwn_write_2(sc, R92C_SIFS_OFDM, 0x100a); 2468 urtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x005ea42b); 2469 urtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a44f); 2470 urtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005ea324); 2471 urtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002fa226); 2472} 2473 2474void 2475urtwn_write_txpower(struct urtwn_softc *sc, int chain, 2476 uint16_t power[URTWN_RIDX_COUNT]) 2477{ 2478 uint32_t reg; 2479 2480 /* Write per-CCK rate Tx power. */ 2481 if (chain == 0) { 2482 reg = urtwn_bb_read(sc, R92C_TXAGC_A_CCK1_MCS32); 2483 reg = RW(reg, R92C_TXAGC_A_CCK1, power[0]); 2484 urtwn_bb_write(sc, R92C_TXAGC_A_CCK1_MCS32, reg); 2485 reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11); 2486 reg = RW(reg, R92C_TXAGC_A_CCK2, power[1]); 2487 reg = RW(reg, R92C_TXAGC_A_CCK55, power[2]); 2488 reg = RW(reg, R92C_TXAGC_A_CCK11, power[3]); 2489 urtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg); 2490 } else { 2491 reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK1_55_MCS32); 2492 reg = RW(reg, R92C_TXAGC_B_CCK1, power[0]); 2493 reg = RW(reg, R92C_TXAGC_B_CCK2, power[1]); 2494 reg = RW(reg, R92C_TXAGC_B_CCK55, power[2]); 2495 urtwn_bb_write(sc, R92C_TXAGC_B_CCK1_55_MCS32, reg); 2496 reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11); 2497 reg = RW(reg, R92C_TXAGC_B_CCK11, power[3]); 2498 urtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg); 2499 } 2500 /* Write per-OFDM rate Tx power. */ 2501 urtwn_bb_write(sc, R92C_TXAGC_RATE18_06(chain), 2502 SM(R92C_TXAGC_RATE06, power[ 4]) | 2503 SM(R92C_TXAGC_RATE09, power[ 5]) | 2504 SM(R92C_TXAGC_RATE12, power[ 6]) | 2505 SM(R92C_TXAGC_RATE18, power[ 7])); 2506 urtwn_bb_write(sc, R92C_TXAGC_RATE54_24(chain), 2507 SM(R92C_TXAGC_RATE24, power[ 8]) | 2508 SM(R92C_TXAGC_RATE36, power[ 9]) | 2509 SM(R92C_TXAGC_RATE48, power[10]) | 2510 SM(R92C_TXAGC_RATE54, power[11])); 2511 /* Write per-MCS Tx power. */ 2512 urtwn_bb_write(sc, R92C_TXAGC_MCS03_MCS00(chain), 2513 SM(R92C_TXAGC_MCS00, power[12]) | 2514 SM(R92C_TXAGC_MCS01, power[13]) | 2515 SM(R92C_TXAGC_MCS02, power[14]) | 2516 SM(R92C_TXAGC_MCS03, power[15])); 2517 urtwn_bb_write(sc, R92C_TXAGC_MCS07_MCS04(chain), 2518 SM(R92C_TXAGC_MCS04, power[16]) | 2519 SM(R92C_TXAGC_MCS05, power[17]) | 2520 SM(R92C_TXAGC_MCS06, power[18]) | 2521 SM(R92C_TXAGC_MCS07, power[19])); 2522 urtwn_bb_write(sc, R92C_TXAGC_MCS11_MCS08(chain), 2523 SM(R92C_TXAGC_MCS08, power[20]) | 2524 SM(R92C_TXAGC_MCS09, power[21]) | 2525 SM(R92C_TXAGC_MCS10, power[22]) | 2526 SM(R92C_TXAGC_MCS11, power[23])); 2527 urtwn_bb_write(sc, R92C_TXAGC_MCS15_MCS12(chain), 2528 SM(R92C_TXAGC_MCS12, power[24]) | 2529 SM(R92C_TXAGC_MCS13, power[25]) | 2530 SM(R92C_TXAGC_MCS14, power[26]) | 2531 SM(R92C_TXAGC_MCS15, power[27])); 2532} 2533 2534void 2535urtwn_get_txpower(struct urtwn_softc *sc, int chain, 2536 struct ieee80211_channel *c, struct ieee80211_channel *extc, 2537 uint16_t power[URTWN_RIDX_COUNT]) 2538{ 2539 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 2540 struct r92c_rom *rom = &sc->rom; 2541 uint16_t cckpow, ofdmpow, htpow, diff, max; 2542 const struct urtwn_txpwr *base; 2543 int ridx, chan, group; 2544 2545 /* Determine channel group. */ 2546 chan = ieee80211_chan2ieee(ic, c); /* XXX center freq! */ 2547 if (chan <= 3) 2548 group = 0; 2549 else if (chan <= 9) 2550 group = 1; 2551 else 2552 group = 2; 2553 2554 /* Get original Tx power based on board type and RF chain. */ 2555 if (!(sc->chip & URTWN_CHIP_92C)) { 2556 if (sc->board_type == R92C_BOARD_TYPE_HIGHPA) 2557 base = &rtl8188ru_txagc[chain]; 2558 else 2559 base = &rtl8192cu_txagc[chain]; 2560 } else 2561 base = &rtl8192cu_txagc[chain]; 2562 2563 memset(power, 0, URTWN_RIDX_COUNT * sizeof(power[0])); 2564 if (sc->regulatory == 0) { 2565 for (ridx = 0; ridx <= 3; ridx++) 2566 power[ridx] = base->pwr[0][ridx]; 2567 } 2568 for (ridx = 4; ridx < URTWN_RIDX_COUNT; ridx++) { 2569 if (sc->regulatory == 3) { 2570 power[ridx] = base->pwr[0][ridx]; 2571 /* Apply vendor limits. */ 2572 if (extc != NULL) 2573 max = rom->ht40_max_pwr[group]; 2574 else 2575 max = rom->ht20_max_pwr[group]; 2576 max = (max >> (chain * 4)) & 0xf; 2577 if (power[ridx] > max) 2578 power[ridx] = max; 2579 } else if (sc->regulatory == 1) { 2580 if (extc == NULL) 2581 power[ridx] = base->pwr[group][ridx]; 2582 } else if (sc->regulatory != 2) 2583 power[ridx] = base->pwr[0][ridx]; 2584 } 2585 2586 /* Compute per-CCK rate Tx power. */ 2587 cckpow = rom->cck_tx_pwr[chain][group]; 2588 for (ridx = 0; ridx <= 3; ridx++) { 2589 power[ridx] += cckpow; 2590 if (power[ridx] > R92C_MAX_TX_PWR) 2591 power[ridx] = R92C_MAX_TX_PWR; 2592 } 2593 2594 htpow = rom->ht40_1s_tx_pwr[chain][group]; 2595 if (sc->ntxchains > 1) { 2596 /* Apply reduction for 2 spatial streams. */ 2597 diff = rom->ht40_2s_tx_pwr_diff[group]; 2598 diff = (diff >> (chain * 4)) & 0xf; 2599 htpow = (htpow > diff) ? htpow - diff : 0; 2600 } 2601 2602 /* Compute per-OFDM rate Tx power. */ 2603 diff = rom->ofdm_tx_pwr_diff[group]; 2604 diff = (diff >> (chain * 4)) & 0xf; 2605 ofdmpow = htpow + diff; /* HT->OFDM correction. */ 2606 for (ridx = 4; ridx <= 11; ridx++) { 2607 power[ridx] += ofdmpow; 2608 if (power[ridx] > R92C_MAX_TX_PWR) 2609 power[ridx] = R92C_MAX_TX_PWR; 2610 } 2611 2612 /* Compute per-MCS Tx power. */ 2613 if (extc == NULL) { 2614 diff = rom->ht20_tx_pwr_diff[group]; 2615 diff = (diff >> (chain * 4)) & 0xf; 2616 htpow += diff; /* HT40->HT20 correction. */ 2617 } 2618 for (ridx = 12; ridx <= 27; ridx++) { 2619 power[ridx] += htpow; 2620 if (power[ridx] > R92C_MAX_TX_PWR) 2621 power[ridx] = R92C_MAX_TX_PWR; 2622 } 2623#ifdef URTWN_DEBUG 2624 if (urtwn_debug >= 4) { 2625 /* Dump per-rate Tx power values. */ 2626 printf("Tx power for chain %d:\n", chain); 2627 for (ridx = 0; ridx < URTWN_RIDX_COUNT; ridx++) 2628 printf("Rate %d = %u\n", ridx, power[ridx]); 2629 } 2630#endif 2631} 2632 2633void 2634urtwn_set_txpower(struct urtwn_softc *sc, struct ieee80211_channel *c, 2635 struct ieee80211_channel *extc) 2636{ 2637 uint16_t power[URTWN_RIDX_COUNT]; 2638 int i; 2639 2640 for (i = 0; i < sc->ntxchains; i++) { 2641 /* Compute per-rate Tx power values. */ 2642 urtwn_get_txpower(sc, i, c, extc, power); 2643 /* Write per-rate Tx power values to hardware. */ 2644 urtwn_write_txpower(sc, i, power); 2645 } 2646} 2647 2648static void 2649urtwn_scan_start(struct ieee80211com *ic) 2650{ 2651 /* XXX do nothing? */ 2652} 2653 2654static void 2655urtwn_scan_end(struct ieee80211com *ic) 2656{ 2657 /* XXX do nothing? */ 2658} 2659 2660static void 2661urtwn_set_channel(struct ieee80211com *ic) 2662{ 2663 struct urtwn_softc *sc = ic->ic_ifp->if_softc; 2664 2665 URTWN_LOCK(sc); 2666 urtwn_set_chan(sc, ic->ic_curchan, NULL); 2667 URTWN_UNLOCK(sc); 2668} 2669 2670static void 2671urtwn_update_mcast(struct ifnet *ifp) 2672{ 2673 /* XXX do nothing? */ 2674} 2675 2676static void 2677urtwn_set_chan(struct urtwn_softc *sc, struct ieee80211_channel *c, 2678 struct ieee80211_channel *extc) 2679{ 2680 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 2681 uint32_t reg; 2682 u_int chan; 2683 int i; 2684 2685 chan = ieee80211_chan2ieee(ic, c); /* XXX center freq! */ 2686 if (chan == 0 || chan == IEEE80211_CHAN_ANY) { 2687 device_printf(sc->sc_dev, 2688 "%s: invalid channel %x\n", __func__, chan); 2689 return; 2690 } 2691 2692 /* Set Tx power for this new channel. */ 2693 urtwn_set_txpower(sc, c, extc); 2694 2695 for (i = 0; i < sc->nrxchains; i++) { 2696 urtwn_rf_write(sc, i, R92C_RF_CHNLBW, 2697 RW(sc->rf_chnlbw[i], R92C_RF_CHNLBW_CHNL, chan)); 2698 } 2699#ifndef IEEE80211_NO_HT 2700 if (extc != NULL) { 2701 /* Is secondary channel below or above primary? */ 2702 int prichlo = c->ic_freq < extc->ic_freq; 2703 2704 urtwn_write_1(sc, R92C_BWOPMODE, 2705 urtwn_read_1(sc, R92C_BWOPMODE) & ~R92C_BWOPMODE_20MHZ); 2706 2707 reg = urtwn_read_1(sc, R92C_RRSR + 2); 2708 reg = (reg & ~0x6f) | (prichlo ? 1 : 2) << 5; 2709 urtwn_write_1(sc, R92C_RRSR + 2, reg); 2710 2711 urtwn_bb_write(sc, R92C_FPGA0_RFMOD, 2712 urtwn_bb_read(sc, R92C_FPGA0_RFMOD) | R92C_RFMOD_40MHZ); 2713 urtwn_bb_write(sc, R92C_FPGA1_RFMOD, 2714 urtwn_bb_read(sc, R92C_FPGA1_RFMOD) | R92C_RFMOD_40MHZ); 2715 2716 /* Set CCK side band. */ 2717 reg = urtwn_bb_read(sc, R92C_CCK0_SYSTEM); 2718 reg = (reg & ~0x00000010) | (prichlo ? 0 : 1) << 4; 2719 urtwn_bb_write(sc, R92C_CCK0_SYSTEM, reg); 2720 2721 reg = urtwn_bb_read(sc, R92C_OFDM1_LSTF); 2722 reg = (reg & ~0x00000c00) | (prichlo ? 1 : 2) << 10; 2723 urtwn_bb_write(sc, R92C_OFDM1_LSTF, reg); 2724 2725 urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2, 2726 urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) & 2727 ~R92C_FPGA0_ANAPARAM2_CBW20); 2728 2729 reg = urtwn_bb_read(sc, 0x818); 2730 reg = (reg & ~0x0c000000) | (prichlo ? 2 : 1) << 26; 2731 urtwn_bb_write(sc, 0x818, reg); 2732 2733 /* Select 40MHz bandwidth. */ 2734 urtwn_rf_write(sc, 0, R92C_RF_CHNLBW, 2735 (sc->rf_chnlbw[0] & ~0xfff) | chan); 2736 } else 2737#endif 2738 { 2739 urtwn_write_1(sc, R92C_BWOPMODE, 2740 urtwn_read_1(sc, R92C_BWOPMODE) | R92C_BWOPMODE_20MHZ); 2741 2742 urtwn_bb_write(sc, R92C_FPGA0_RFMOD, 2743 urtwn_bb_read(sc, R92C_FPGA0_RFMOD) & ~R92C_RFMOD_40MHZ); 2744 urtwn_bb_write(sc, R92C_FPGA1_RFMOD, 2745 urtwn_bb_read(sc, R92C_FPGA1_RFMOD) & ~R92C_RFMOD_40MHZ); 2746 2747 urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2, 2748 urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) | 2749 R92C_FPGA0_ANAPARAM2_CBW20); 2750 2751 /* Select 20MHz bandwidth. */ 2752 urtwn_rf_write(sc, 0, R92C_RF_CHNLBW, 2753 (sc->rf_chnlbw[0] & ~0xfff) | R92C_RF_CHNLBW_BW20 | chan); 2754 } 2755} 2756 2757static void 2758urtwn_iq_calib(struct urtwn_softc *sc) 2759{ 2760 /* TODO */ 2761} 2762 2763static void 2764urtwn_lc_calib(struct urtwn_softc *sc) 2765{ 2766 uint32_t rf_ac[2]; 2767 uint8_t txmode; 2768 int i; 2769 2770 txmode = urtwn_read_1(sc, R92C_OFDM1_LSTF + 3); 2771 if ((txmode & 0x70) != 0) { 2772 /* Disable all continuous Tx. */ 2773 urtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode & ~0x70); 2774 2775 /* Set RF mode to standby mode. */ 2776 for (i = 0; i < sc->nrxchains; i++) { 2777 rf_ac[i] = urtwn_rf_read(sc, i, R92C_RF_AC); 2778 urtwn_rf_write(sc, i, R92C_RF_AC, 2779 RW(rf_ac[i], R92C_RF_AC_MODE, 2780 R92C_RF_AC_MODE_STANDBY)); 2781 } 2782 } else { 2783 /* Block all Tx queues. */ 2784 urtwn_write_1(sc, R92C_TXPAUSE, 0xff); 2785 } 2786 /* Start calibration. */ 2787 urtwn_rf_write(sc, 0, R92C_RF_CHNLBW, 2788 urtwn_rf_read(sc, 0, R92C_RF_CHNLBW) | R92C_RF_CHNLBW_LCSTART); 2789 2790 /* Give calibration the time to complete. */ 2791 usb_pause_mtx(&sc->sc_mtx, 100); 2792 2793 /* Restore configuration. */ 2794 if ((txmode & 0x70) != 0) { 2795 /* Restore Tx mode. */ 2796 urtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode); 2797 /* Restore RF mode. */ 2798 for (i = 0; i < sc->nrxchains; i++) 2799 urtwn_rf_write(sc, i, R92C_RF_AC, rf_ac[i]); 2800 } else { 2801 /* Unblock all Tx queues. */ 2802 urtwn_write_1(sc, R92C_TXPAUSE, 0x00); 2803 } 2804} 2805 2806static void 2807urtwn_init_locked(void *arg) 2808{ 2809 struct urtwn_softc *sc = arg; 2810 struct ifnet *ifp = sc->sc_ifp; 2811 uint32_t reg; 2812 int error; 2813 2814 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 2815 urtwn_stop_locked(ifp); 2816 2817 /* Init firmware commands ring. */ 2818 sc->fwcur = 0; 2819 2820 /* Allocate Tx/Rx buffers. */ 2821 error = urtwn_alloc_rx_list(sc); 2822 if (error != 0) 2823 goto fail; 2824 2825 error = urtwn_alloc_tx_list(sc); 2826 if (error != 0) 2827 goto fail; 2828 2829 /* Power on adapter. */ 2830 error = urtwn_power_on(sc); 2831 if (error != 0) 2832 goto fail; 2833 2834 /* Initialize DMA. */ 2835 error = urtwn_dma_init(sc); 2836 if (error != 0) 2837 goto fail; 2838 2839 /* Set info size in Rx descriptors (in 64-bit words). */ 2840 urtwn_write_1(sc, R92C_RX_DRVINFO_SZ, 4); 2841 2842 /* Init interrupts. */ 2843 urtwn_write_4(sc, R92C_HISR, 0xffffffff); 2844 urtwn_write_4(sc, R92C_HIMR, 0xffffffff); 2845 2846 /* Set MAC address. */ 2847 urtwn_write_region_1(sc, R92C_MACID, IF_LLADDR(ifp), 2848 IEEE80211_ADDR_LEN); 2849 2850 /* Set initial network type. */ 2851 reg = urtwn_read_4(sc, R92C_CR); 2852 reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_INFRA); 2853 urtwn_write_4(sc, R92C_CR, reg); 2854 2855 urtwn_rxfilter_init(sc); 2856 2857 reg = urtwn_read_4(sc, R92C_RRSR); 2858 reg = RW(reg, R92C_RRSR_RATE_BITMAP, R92C_RRSR_RATE_CCK_ONLY_1M); 2859 urtwn_write_4(sc, R92C_RRSR, reg); 2860 2861 /* Set short/long retry limits. */ 2862 urtwn_write_2(sc, R92C_RL, 2863 SM(R92C_RL_SRL, 0x30) | SM(R92C_RL_LRL, 0x30)); 2864 2865 /* Initialize EDCA parameters. */ 2866 urtwn_edca_init(sc); 2867 2868 /* Setup rate fallback. */ 2869 urtwn_write_4(sc, R92C_DARFRC + 0, 0x00000000); 2870 urtwn_write_4(sc, R92C_DARFRC + 4, 0x10080404); 2871 urtwn_write_4(sc, R92C_RARFRC + 0, 0x04030201); 2872 urtwn_write_4(sc, R92C_RARFRC + 4, 0x08070605); 2873 2874 urtwn_write_1(sc, R92C_FWHW_TXQ_CTRL, 2875 urtwn_read_1(sc, R92C_FWHW_TXQ_CTRL) | 2876 R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW); 2877 /* Set ACK timeout. */ 2878 urtwn_write_1(sc, R92C_ACKTO, 0x40); 2879 2880 /* Setup USB aggregation. */ 2881 reg = urtwn_read_4(sc, R92C_TDECTRL); 2882 reg = RW(reg, R92C_TDECTRL_BLK_DESC_NUM, 6); 2883 urtwn_write_4(sc, R92C_TDECTRL, reg); 2884 urtwn_write_1(sc, R92C_TRXDMA_CTRL, 2885 urtwn_read_1(sc, R92C_TRXDMA_CTRL) | 2886 R92C_TRXDMA_CTRL_RXDMA_AGG_EN); 2887 urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION, 2888 urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) | 2889 R92C_USB_SPECIAL_OPTION_AGG_EN); 2890 urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48); 2891 urtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4); 2892 urtwn_write_1(sc, R92C_USB_AGG_TH, 8); 2893 urtwn_write_1(sc, R92C_USB_AGG_TO, 6); 2894 2895 /* Initialize beacon parameters. */ 2896 urtwn_write_2(sc, R92C_TBTT_PROHIBIT, 0x6404); 2897 urtwn_write_1(sc, R92C_DRVERLYINT, 0x05); 2898 urtwn_write_1(sc, R92C_BCNDMATIM, 0x02); 2899 urtwn_write_2(sc, R92C_BCNTCFG, 0x660f); 2900 2901 /* Setup AMPDU aggregation. */ 2902 urtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631); /* MCS7~0 */ 2903 urtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16); 2904 urtwn_write_2(sc, 0x4ca, 0x0708); 2905 2906 urtwn_write_1(sc, R92C_BCN_MAX_ERR, 0xff); 2907 urtwn_write_1(sc, R92C_BCN_CTRL, R92C_BCN_CTRL_DIS_TSF_UDT0); 2908 2909 /* Load 8051 microcode. */ 2910 error = urtwn_load_firmware(sc); 2911 if (error != 0) 2912 goto fail; 2913 2914 /* Initialize MAC/BB/RF blocks. */ 2915 urtwn_mac_init(sc); 2916 urtwn_bb_init(sc); 2917 urtwn_rf_init(sc); 2918 2919 /* Turn CCK and OFDM blocks on. */ 2920 reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD); 2921 reg |= R92C_RFMOD_CCK_EN; 2922 urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg); 2923 reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD); 2924 reg |= R92C_RFMOD_OFDM_EN; 2925 urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg); 2926 2927 /* Clear per-station keys table. */ 2928 urtwn_cam_init(sc); 2929 2930 /* Enable hardware sequence numbering. */ 2931 urtwn_write_1(sc, R92C_HWSEQ_CTRL, 0xff); 2932 2933 /* Perform LO and IQ calibrations. */ 2934 urtwn_iq_calib(sc); 2935 /* Perform LC calibration. */ 2936 urtwn_lc_calib(sc); 2937 2938 /* Fix USB interference issue. */ 2939 urtwn_write_1(sc, 0xfe40, 0xe0); 2940 urtwn_write_1(sc, 0xfe41, 0x8d); 2941 urtwn_write_1(sc, 0xfe42, 0x80); 2942 2943 urtwn_pa_bias_init(sc); 2944 2945 /* Initialize GPIO setting. */ 2946 urtwn_write_1(sc, R92C_GPIO_MUXCFG, 2947 urtwn_read_1(sc, R92C_GPIO_MUXCFG) & ~R92C_GPIO_MUXCFG_ENBT); 2948 2949 /* Fix for lower temperature. */ 2950 urtwn_write_1(sc, 0x15, 0xe9); 2951 2952 usbd_transfer_start(sc->sc_xfer[URTWN_BULK_RX]); 2953 2954 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 2955 ifp->if_drv_flags |= IFF_DRV_RUNNING; 2956 2957 callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc); 2958fail: 2959 return; 2960} 2961 2962static void 2963urtwn_init(void *arg) 2964{ 2965 struct urtwn_softc *sc = arg; 2966 2967 URTWN_LOCK(sc); 2968 urtwn_init_locked(arg); 2969 URTWN_UNLOCK(sc); 2970} 2971 2972static void 2973urtwn_stop_locked(struct ifnet *ifp) 2974{ 2975 struct urtwn_softc *sc = ifp->if_softc; 2976 2977 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 2978 2979 callout_stop(&sc->sc_watchdog_ch); 2980 urtwn_abort_xfers(sc); 2981} 2982 2983static void 2984urtwn_stop(struct ifnet *ifp) 2985{ 2986 struct urtwn_softc *sc = ifp->if_softc; 2987 2988 URTWN_LOCK(sc); 2989 urtwn_stop_locked(ifp); 2990 URTWN_UNLOCK(sc); 2991} 2992 2993static void 2994urtwn_abort_xfers(struct urtwn_softc *sc) 2995{ 2996 int i; 2997 2998 URTWN_ASSERT_LOCKED(sc); 2999 3000 /* abort any pending transfers */ 3001 for (i = 0; i < URTWN_N_TRANSFER; i++) 3002 usbd_transfer_stop(sc->sc_xfer[i]); 3003} 3004 3005static int 3006urtwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 3007 const struct ieee80211_bpf_params *params) 3008{ 3009 struct ieee80211com *ic = ni->ni_ic; 3010 struct ifnet *ifp = ic->ic_ifp; 3011 struct urtwn_softc *sc = ifp->if_softc; 3012 struct urtwn_data *bf; 3013 3014 /* prevent management frames from being sent if we're not ready */ 3015 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { 3016 m_freem(m); 3017 ieee80211_free_node(ni); 3018 return (ENETDOWN); 3019 } 3020 URTWN_LOCK(sc); 3021 bf = urtwn_getbuf(sc); 3022 if (bf == NULL) { 3023 ieee80211_free_node(ni); 3024 m_freem(m); 3025 URTWN_UNLOCK(sc); 3026 return (ENOBUFS); 3027 } 3028 3029 ifp->if_opackets++; 3030 if (urtwn_tx_start(sc, ni, m, bf) != 0) { 3031 ieee80211_free_node(ni); 3032 ifp->if_oerrors++; 3033 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); 3034 URTWN_UNLOCK(sc); 3035 return (EIO); 3036 } 3037 URTWN_UNLOCK(sc); 3038 3039 sc->sc_txtimer = 5; 3040 return (0); 3041} 3042 3043static device_method_t urtwn_methods[] = { 3044 /* Device interface */ 3045 DEVMETHOD(device_probe, urtwn_match), 3046 DEVMETHOD(device_attach, urtwn_attach), 3047 DEVMETHOD(device_detach, urtwn_detach), 3048 3049 { 0, 0 } 3050}; 3051 3052static driver_t urtwn_driver = { 3053 "urtwn", 3054 urtwn_methods, 3055 sizeof(struct urtwn_softc) 3056}; 3057 3058static devclass_t urtwn_devclass; 3059 3060DRIVER_MODULE(urtwn, uhub, urtwn_driver, urtwn_devclass, NULL, NULL); 3061MODULE_DEPEND(urtwn, usb, 1, 1, 1); 3062MODULE_DEPEND(urtwn, wlan, 1, 1, 1); 3063MODULE_DEPEND(urtwn, firmware, 1, 1, 1); 3064MODULE_VERSION(urtwn, 1); 3065