1149871Sscottl 2149871Sscottl/*- 3136849Sscottl * Copyright (c) 2005, 2006 4136849Sscottl * Damien Bergamini <damien.bergamini@free.fr> 5136849Sscottl * 6136849Sscottl * Copyright (c) 2006, 2008 7136849Sscottl * Hans Petter Selasky <hselasky@FreeBSD.org> 8136849Sscottl * 9136849Sscottl * Permission to use, copy, modify, and distribute this software for any 10136849Sscottl * purpose with or without fee is hereby granted, provided that the above 11136849Sscottl * copyright notice and this permission notice appear in all copies. 12136849Sscottl * 13136849Sscottl * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14136849Sscottl * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15136849Sscottl * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16136849Sscottl * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17136849Sscottl * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18136849Sscottl * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19136849Sscottl * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20136849Sscottl */ 21136849Sscottl 22136849Sscottl#include <sys/cdefs.h> 23136849Sscottl/*- 24136849Sscottl * Ralink Technology RT2500USB chipset driver 25136849Sscottl * http://www.ralinktech.com/ 26227912Smarius */ 27227912Smarius 28227912Smarius#include "opt_wlan.h" 29149871Sscottl 30136849Sscottl#include <sys/param.h> 31136849Sscottl#include <sys/sockio.h> 32136849Sscottl#include <sys/sysctl.h> 33136849Sscottl#include <sys/lock.h> 34136849Sscottl#include <sys/mutex.h> 35136849Sscottl#include <sys/mbuf.h> 36136849Sscottl#include <sys/kernel.h> 37136849Sscottl#include <sys/socket.h> 38136849Sscottl#include <sys/systm.h> 39136849Sscottl#include <sys/malloc.h> 40136849Sscottl#include <sys/module.h> 41136849Sscottl#include <sys/bus.h> 42136849Sscottl#include <sys/endian.h> 43149871Sscottl#include <sys/kdb.h> 44149871Sscottl 45269617Sjhb#include <net/bpf.h> 46149871Sscottl#include <net/if.h> 47136849Sscottl#include <net/if_var.h> 48136849Sscottl#include <net/if_arp.h> 49136849Sscottl#include <net/ethernet.h> 50149871Sscottl#include <net/if_dl.h> 51149871Sscottl#include <net/if_media.h> 52149871Sscottl#include <net/if_types.h> 53149871Sscottl 54136849Sscottl#ifdef INET 55136849Sscottl#include <netinet/in.h> 56136849Sscottl#include <netinet/in_systm.h> 57143039Sscottl#include <netinet/in_var.h> 58136849Sscottl#include <netinet/if_ether.h> 59149871Sscottl#include <netinet/ip.h> 60136849Sscottl#endif 61136849Sscottl 62136849Sscottl#include <net80211/ieee80211_var.h> 63149871Sscottl#include <net80211/ieee80211_regdomain.h> 64136849Sscottl#include <net80211/ieee80211_radiotap.h> 65136849Sscottl#include <net80211/ieee80211_ratectl.h> 66136849Sscottl 67136849Sscottl#include <dev/usb/usb.h> 68136849Sscottl#include <dev/usb/usbdi.h> 69149871Sscottl#include "usbdevs.h" 70136849Sscottl 71136849Sscottl#define USB_DEBUG_VAR ural_debug 72136849Sscottl#include <dev/usb/usb_debug.h> 73149871Sscottl 74149871Sscottl#include <dev/usb/wlan/if_uralreg.h> 75149871Sscottl#include <dev/usb/wlan/if_uralvar.h> 76149871Sscottl 77149871Sscottl#ifdef USB_DEBUG 78149871Sscottlstatic int ural_debug = 0; 79149871Sscottl 80149871Sscottlstatic SYSCTL_NODE(_hw_usb, OID_AUTO, ural, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 81149871Sscottl "USB ural"); 82149871SscottlSYSCTL_INT(_hw_usb_ural, OID_AUTO, debug, CTLFLAG_RWTUN, &ural_debug, 0, 83149871Sscottl "Debug level"); 84149871Sscottl#endif 85149871Sscottl 86149871Sscottl#define URAL_RSSI(rssi) \ 87149871Sscottl ((rssi) > (RAL_NOISE_FLOOR + RAL_RSSI_CORR) ? \ 88149871Sscottl ((rssi) - (RAL_NOISE_FLOOR + RAL_RSSI_CORR)) : 0) 89190863Sdelphij 90227912Smarius/* various supported device vendors/products */ 91149871Sscottlstatic const STRUCT_USB_HOST_ID ural_devs[] = { 92149871Sscottl#define URAL_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } 93149871Sscottl URAL_DEV(ASUS, WL167G), 94149871Sscottl URAL_DEV(ASUS, RT2570), 95149871Sscottl URAL_DEV(BELKIN, F5D7050), 96149871Sscottl URAL_DEV(BELKIN, F5D7051), 97149871Sscottl URAL_DEV(CISCOLINKSYS, HU200TS), 98149871Sscottl URAL_DEV(CISCOLINKSYS, WUSB54G), 99149871Sscottl URAL_DEV(CISCOLINKSYS, WUSB54GP), 100149871Sscottl URAL_DEV(CONCEPTRONIC2, C54RU), 101149871Sscottl URAL_DEV(DLINK, DWLG122), 102149871Sscottl URAL_DEV(GIGABYTE, GN54G), 103236379Seadler URAL_DEV(GIGABYTE, GNWBKG), 104149871Sscottl URAL_DEV(GUILLEMOT, HWGUSB254), 105149871Sscottl URAL_DEV(MELCO, KG54), 106149871Sscottl URAL_DEV(MELCO, KG54AI), 107149871Sscottl URAL_DEV(MELCO, KG54YB), 108149871Sscottl URAL_DEV(MELCO, NINWIFI), 109149871Sscottl URAL_DEV(MSI, RT2570), 110149871Sscottl URAL_DEV(MSI, RT2570_2), 111149871Sscottl URAL_DEV(MSI, RT2570_3), 112149871Sscottl URAL_DEV(NOVATECH, NV902), 113149871Sscottl URAL_DEV(RALINK, RT2570), 114269617Sjhb URAL_DEV(RALINK, RT2570_2), 115136849Sscottl URAL_DEV(RALINK, RT2570_3), 116136849Sscottl URAL_DEV(SIEMENS2, WL54G), 117136849Sscottl URAL_DEV(SMC, 2862WG), 118136849Sscottl URAL_DEV(SPHAIRON, UB801R), 119136849Sscottl URAL_DEV(SURECOM, RT2570), 120136849Sscottl URAL_DEV(VTECH, RT2570), 121136849Sscottl URAL_DEV(ZINWELL, RT2570), 122136849Sscottl#undef URAL_DEV 123136849Sscottl}; 124136849Sscottl 125136849Sscottlstatic usb_callback_t ural_bulk_read_callback; 126136849Sscottlstatic usb_callback_t ural_bulk_write_callback; 127136849Sscottl 128136849Sscottlstatic usb_error_t ural_do_request(struct ural_softc *sc, 129136849Sscottl struct usb_device_request *req, void *data); 130136849Sscottlstatic struct ieee80211vap *ural_vap_create(struct ieee80211com *, 131136849Sscottl const char [IFNAMSIZ], int, enum ieee80211_opmode, 132136849Sscottl int, const uint8_t [IEEE80211_ADDR_LEN], 133136849Sscottl const uint8_t [IEEE80211_ADDR_LEN]); 134136849Sscottlstatic void ural_vap_delete(struct ieee80211vap *); 135136849Sscottlstatic void ural_tx_free(struct ural_tx_data *, int); 136136849Sscottlstatic void ural_setup_tx_list(struct ural_softc *); 137136849Sscottlstatic void ural_unsetup_tx_list(struct ural_softc *); 138136849Sscottlstatic int ural_newstate(struct ieee80211vap *, 139269617Sjhb enum ieee80211_state, int); 140269617Sjhbstatic void ural_setup_tx_desc(struct ural_softc *, 141136849Sscottl struct ural_tx_desc *, uint32_t, int, int); 142136849Sscottlstatic int ural_tx_bcn(struct ural_softc *, struct mbuf *, 143149871Sscottl struct ieee80211_node *); 144136849Sscottlstatic int ural_tx_mgt(struct ural_softc *, struct mbuf *, 145136849Sscottl struct ieee80211_node *); 146136849Sscottlstatic int ural_tx_data(struct ural_softc *, struct mbuf *, 147136849Sscottl struct ieee80211_node *); 148136849Sscottlstatic int ural_transmit(struct ieee80211com *, struct mbuf *); 149136849Sscottlstatic void ural_start(struct ural_softc *); 150136849Sscottlstatic void ural_parent(struct ieee80211com *); 151136849Sscottlstatic void ural_set_testmode(struct ural_softc *); 152136849Sscottlstatic void ural_eeprom_read(struct ural_softc *, uint16_t, void *, 153136849Sscottl int); 154136849Sscottlstatic uint16_t ural_read(struct ural_softc *, uint16_t); 155136849Sscottlstatic void ural_read_multi(struct ural_softc *, uint16_t, void *, 156136849Sscottl int); 157269617Sjhbstatic void ural_write(struct ural_softc *, uint16_t, uint16_t); 158269617Sjhbstatic void ural_write_multi(struct ural_softc *, uint16_t, void *, 159136849Sscottl int) __unused; 160190809Sdelphijstatic void ural_bbp_write(struct ural_softc *, uint8_t, uint8_t); 161136849Sscottlstatic uint8_t ural_bbp_read(struct ural_softc *, uint8_t); 162136849Sscottlstatic void ural_rf_write(struct ural_softc *, uint8_t, uint32_t); 163136849Sscottlstatic void ural_scan_start(struct ieee80211com *); 164136849Sscottlstatic void ural_scan_end(struct ieee80211com *); 165136849Sscottlstatic void ural_getradiocaps(struct ieee80211com *, int, int *, 166136849Sscottl struct ieee80211_channel[]); 167298955Spfgstatic void ural_set_channel(struct ieee80211com *); 168136849Sscottlstatic void ural_set_chan(struct ural_softc *, 169136849Sscottl struct ieee80211_channel *); 170136849Sscottlstatic void ural_disable_rf_tune(struct ural_softc *); 171136849Sscottlstatic void ural_enable_tsf_sync(struct ural_softc *); 172136849Sscottlstatic void ural_enable_tsf(struct ural_softc *); 173136849Sscottlstatic void ural_update_slot(struct ural_softc *); 174136849Sscottlstatic void ural_set_txpreamble(struct ural_softc *); 175136849Sscottlstatic void ural_set_basicrates(struct ural_softc *, 176136849Sscottl const struct ieee80211_channel *); 177149871Sscottlstatic void ural_set_bssid(struct ural_softc *, const uint8_t *); 178136849Sscottlstatic void ural_set_macaddr(struct ural_softc *, const uint8_t *); 179149871Sscottlstatic void ural_update_promisc(struct ieee80211com *); 180149871Sscottlstatic void ural_setpromisc(struct ural_softc *); 181149871Sscottlstatic const char *ural_get_rf(int); 182149871Sscottlstatic void ural_read_eeprom(struct ural_softc *); 183149871Sscottlstatic int ural_bbp_init(struct ural_softc *); 184149871Sscottlstatic void ural_set_txantenna(struct ural_softc *, int); 185149871Sscottlstatic void ural_set_rxantenna(struct ural_softc *, int); 186149871Sscottlstatic void ural_init(struct ural_softc *); 187149871Sscottlstatic void ural_stop(struct ural_softc *); 188149871Sscottlstatic int ural_raw_xmit(struct ieee80211_node *, struct mbuf *, 189149871Sscottl const struct ieee80211_bpf_params *); 190149871Sscottlstatic void ural_ratectl_start(struct ural_softc *, 191149871Sscottl struct ieee80211_node *); 192149871Sscottlstatic void ural_ratectl_timeout(void *); 193149871Sscottlstatic void ural_ratectl_task(void *, int); 194149871Sscottlstatic int ural_pause(struct ural_softc *sc, int timeout); 195149871Sscottl 196136849Sscottl/* 197149871Sscottl * Default values for MAC registers; values taken from the reference driver. 198136849Sscottl */ 199136849Sscottlstatic const struct { 200136849Sscottl uint16_t reg; 201136849Sscottl uint16_t val; 202136849Sscottl} ural_def_mac[] = { 203136849Sscottl { RAL_TXRX_CSR5, 0x8c8d }, 204136849Sscottl { RAL_TXRX_CSR6, 0x8b8a }, 205136849Sscottl { RAL_TXRX_CSR7, 0x8687 }, 206136849Sscottl { RAL_TXRX_CSR8, 0x0085 }, 207136849Sscottl { RAL_MAC_CSR13, 0x1111 }, 208136849Sscottl { RAL_MAC_CSR14, 0x1e11 }, 209136849Sscottl { RAL_TXRX_CSR21, 0xe78f }, 210136849Sscottl { RAL_MAC_CSR9, 0xff1d }, 211136849Sscottl { RAL_MAC_CSR11, 0x0002 }, 212136849Sscottl { RAL_MAC_CSR22, 0x0053 }, 213136849Sscottl { RAL_MAC_CSR15, 0x0000 }, 214136849Sscottl { RAL_MAC_CSR8, RAL_FRAME_SIZE }, 215136849Sscottl { RAL_TXRX_CSR19, 0x0000 }, 216149871Sscottl { RAL_TXRX_CSR18, 0x005a }, 217149871Sscottl { RAL_PHY_CSR2, 0x0000 }, 218149871Sscottl { RAL_TXRX_CSR0, 0x1ec0 }, 219136849Sscottl { RAL_PHY_CSR4, 0x000f } 220136849Sscottl}; 221136849Sscottl 222136849Sscottl/* 223149871Sscottl * Default values for BBP registers; values taken from the reference driver. 224149871Sscottl */ 225149871Sscottlstatic const struct { 226149871Sscottl uint8_t reg; 227149871Sscottl uint8_t val; 228149871Sscottl} ural_def_bbp[] = { 229149871Sscottl { 3, 0x02 }, 230149871Sscottl { 4, 0x19 }, 231136849Sscottl { 14, 0x1c }, 232136849Sscottl { 15, 0x30 }, 233136849Sscottl { 16, 0xac }, 234136849Sscottl { 17, 0x48 }, 235136849Sscottl { 18, 0x18 }, 236136849Sscottl { 19, 0xff }, 237149871Sscottl { 20, 0x1e }, 238149871Sscottl { 21, 0x08 }, 239149871Sscottl { 22, 0x08 }, 240136849Sscottl { 23, 0x08 }, 241136849Sscottl { 24, 0x80 }, 242136849Sscottl { 25, 0x50 }, 243136849Sscottl { 26, 0x08 }, 244136849Sscottl { 27, 0x23 }, 245136849Sscottl { 30, 0x10 }, 246136849Sscottl { 31, 0x2b }, 247136849Sscottl { 32, 0xb9 }, 248136849Sscottl { 34, 0x12 }, 249136849Sscottl { 35, 0x50 }, 250136849Sscottl { 39, 0xc4 }, 251136849Sscottl { 40, 0x02 }, 252136849Sscottl { 41, 0x60 }, 253136849Sscottl { 53, 0x10 }, 254190809Sdelphij { 54, 0x18 }, 255136849Sscottl { 56, 0x08 }, 256136849Sscottl { 57, 0x10 }, 257136849Sscottl { 58, 0x08 }, 258136849Sscottl { 61, 0x60 }, 259149871Sscottl { 62, 0x10 }, 260136849Sscottl { 75, 0xff } 261136849Sscottl}; 262136849Sscottl 263136849Sscottl/* 264136849Sscottl * Default values for RF register R2 indexed by channel numbers. 265149871Sscottl */ 266149871Sscottlstatic const uint32_t ural_rf2522_r2[] = { 267149871Sscottl 0x307f6, 0x307fb, 0x30800, 0x30805, 0x3080a, 0x3080f, 0x30814, 268136849Sscottl 0x30819, 0x3081e, 0x30823, 0x30828, 0x3082d, 0x30832, 0x3083e 269136849Sscottl}; 270149871Sscottl 271136849Sscottlstatic const uint32_t ural_rf2523_r2[] = { 272136849Sscottl 0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d, 273136849Sscottl 0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346 274136849Sscottl}; 275190809Sdelphij 276149871Sscottlstatic const uint32_t ural_rf2524_r2[] = { 277149871Sscottl 0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d, 278136849Sscottl 0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346 279136849Sscottl}; 280136849Sscottl 281136849Sscottlstatic const uint32_t ural_rf2525_r2[] = { 282190809Sdelphij 0x20327, 0x20328, 0x20329, 0x2032a, 0x2032b, 0x2032c, 0x2032d, 283149871Sscottl 0x2032e, 0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20346 284149871Sscottl}; 285149871Sscottl 286149871Sscottlstatic const uint32_t ural_rf2525_hi_r2[] = { 287149871Sscottl 0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20344, 0x20345, 288136849Sscottl 0x20346, 0x20347, 0x20348, 0x20349, 0x2034a, 0x2034b, 0x2034e 289136849Sscottl}; 290136849Sscottl 291136849Sscottlstatic const uint32_t ural_rf2525e_r2[] = { 292190809Sdelphij 0x2044d, 0x2044e, 0x2044f, 0x20460, 0x20461, 0x20462, 0x20463, 293149871Sscottl 0x20464, 0x20465, 0x20466, 0x20467, 0x20468, 0x20469, 0x2046b 294149871Sscottl}; 295136849Sscottl 296136849Sscottlstatic const uint32_t ural_rf2526_hi_r2[] = { 297136849Sscottl 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d, 0x0022d, 298136849Sscottl 0x0022e, 0x0022e, 0x0022f, 0x0022d, 0x00240, 0x00240, 0x00241 299190809Sdelphij}; 300149871Sscottl 301149871Sscottlstatic const uint32_t ural_rf2526_r2[] = { 302136849Sscottl 0x00226, 0x00227, 0x00227, 0x00228, 0x00228, 0x00229, 0x00229, 303136849Sscottl 0x0022a, 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d 304136849Sscottl}; 305136849Sscottl 306136849Sscottl/* 307136849Sscottl * For dual-band RF, RF registers R1 and R4 also depend on channel number; 308136849Sscottl * values taken from the reference driver. 309136849Sscottl */ 310149871Sscottlstatic const struct { 311190809Sdelphij uint8_t chan; 312298955Spfg uint32_t r1; 313149871Sscottl uint32_t r2; 314136849Sscottl uint32_t r4; 315136849Sscottl} ural_rf5222[] = { 316136849Sscottl { 1, 0x08808, 0x0044d, 0x00282 }, 317136849Sscottl { 2, 0x08808, 0x0044e, 0x00282 }, 318136849Sscottl { 3, 0x08808, 0x0044f, 0x00282 }, 319136849Sscottl { 4, 0x08808, 0x00460, 0x00282 }, 320136849Sscottl { 5, 0x08808, 0x00461, 0x00282 }, 321136849Sscottl { 6, 0x08808, 0x00462, 0x00282 }, 322136849Sscottl { 7, 0x08808, 0x00463, 0x00282 }, 323136849Sscottl { 8, 0x08808, 0x00464, 0x00282 }, 324136849Sscottl { 9, 0x08808, 0x00465, 0x00282 }, 325149871Sscottl { 10, 0x08808, 0x00466, 0x00282 }, 326149871Sscottl { 11, 0x08808, 0x00467, 0x00282 }, 327136849Sscottl { 12, 0x08808, 0x00468, 0x00282 }, 328136849Sscottl { 13, 0x08808, 0x00469, 0x00282 }, 329149871Sscottl { 14, 0x08808, 0x0046b, 0x00286 }, 330149871Sscottl 331149871Sscottl { 36, 0x08804, 0x06225, 0x00287 }, 332136849Sscottl { 40, 0x08804, 0x06226, 0x00287 }, 333136849Sscottl { 44, 0x08804, 0x06227, 0x00287 }, 334136849Sscottl { 48, 0x08804, 0x06228, 0x00287 }, 335149871Sscottl { 52, 0x08804, 0x06229, 0x00287 }, 336149871Sscottl { 56, 0x08804, 0x0622a, 0x00287 }, 337136849Sscottl { 60, 0x08804, 0x0622b, 0x00287 }, 338136849Sscottl { 64, 0x08804, 0x0622c, 0x00287 }, 339149871Sscottl 340149871Sscottl { 100, 0x08804, 0x02200, 0x00283 }, 341149871Sscottl { 104, 0x08804, 0x02201, 0x00283 }, 342136849Sscottl { 108, 0x08804, 0x02202, 0x00283 }, 343136849Sscottl { 112, 0x08804, 0x02203, 0x00283 }, 344136849Sscottl { 116, 0x08804, 0x02204, 0x00283 }, 345149871Sscottl { 120, 0x08804, 0x02205, 0x00283 }, 346149871Sscottl { 124, 0x08804, 0x02206, 0x00283 }, 347149871Sscottl { 128, 0x08804, 0x02207, 0x00283 }, 348136849Sscottl { 132, 0x08804, 0x02208, 0x00283 }, 349136849Sscottl { 136, 0x08804, 0x02209, 0x00283 }, 350136849Sscottl { 140, 0x08804, 0x0220a, 0x00283 }, 351136849Sscottl 352136849Sscottl { 149, 0x08808, 0x02429, 0x00281 }, 353136849Sscottl { 153, 0x08808, 0x0242b, 0x00281 }, 354149871Sscottl { 157, 0x08808, 0x0242d, 0x00281 }, 355149871Sscottl { 161, 0x08808, 0x0242f, 0x00281 } 356149871Sscottl}; 357136849Sscottl 358136849Sscottlstatic const uint8_t ural_chan_5ghz[] = 359136849Sscottl { 36, 40, 44, 48, 52, 56, 60, 64, 360136849Sscottl 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 361149871Sscottl 149, 153, 157, 161 }; 362149871Sscottl 363136849Sscottlstatic const struct usb_config ural_config[URAL_N_TRANSFER] = { 364136849Sscottl [URAL_BULK_WR] = { 365149871Sscottl .type = UE_BULK, 366149871Sscottl .endpoint = UE_ADDR_ANY, 367149871Sscottl .direction = UE_DIR_OUT, 368136849Sscottl .bufsize = (RAL_FRAME_SIZE + RAL_TX_DESC_SIZE + 4), 369136849Sscottl .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, 370136849Sscottl .callback = ural_bulk_write_callback, 371136849Sscottl .timeout = 5000, /* ms */ 372136849Sscottl }, 373136849Sscottl [URAL_BULK_RD] = { 374136849Sscottl .type = UE_BULK, 375136849Sscottl .endpoint = UE_ADDR_ANY, 376136849Sscottl .direction = UE_DIR_IN, 377149871Sscottl .bufsize = (RAL_FRAME_SIZE + RAL_RX_DESC_SIZE), 378149871Sscottl .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 379149871Sscottl .callback = ural_bulk_read_callback, 380136849Sscottl }, 381136849Sscottl}; 382136849Sscottl 383136849Sscottlstatic device_probe_t ural_match; 384136849Sscottlstatic device_attach_t ural_attach; 385136849Sscottlstatic device_detach_t ural_detach; 386136849Sscottl 387136849Sscottlstatic device_method_t ural_methods[] = { 388136849Sscottl /* Device interface */ 389136849Sscottl DEVMETHOD(device_probe, ural_match), 390149871Sscottl DEVMETHOD(device_attach, ural_attach), 391136849Sscottl DEVMETHOD(device_detach, ural_detach), 392136849Sscottl DEVMETHOD_END 393136849Sscottl}; 394149871Sscottl 395149871Sscottlstatic driver_t ural_driver = { 396149871Sscottl .name = "ural", 397149871Sscottl .methods = ural_methods, 398136849Sscottl .size = sizeof(struct ural_softc), 399136849Sscottl}; 400149871Sscottl 401136849SscottlDRIVER_MODULE(ural, uhub, ural_driver, NULL, NULL); 402136849SscottlMODULE_DEPEND(ural, usb, 1, 1, 1); 403149871SscottlMODULE_DEPEND(ural, wlan, 1, 1, 1); 404136849SscottlMODULE_VERSION(ural, 1); 405136849SscottlUSB_PNP_HOST_INFO(ural_devs); 406136849Sscottl 407149871Sscottlstatic int 408136849Sscottlural_match(device_t self) 409136849Sscottl{ 410136849Sscottl struct usb_attach_arg *uaa = device_get_ivars(self); 411149871Sscottl 412136849Sscottl if (uaa->usb_mode != USB_MODE_HOST) 413136849Sscottl return (ENXIO); 414149871Sscottl if (uaa->info.bConfigIndex != 0) 415149871Sscottl return (ENXIO); 416149871Sscottl if (uaa->info.bIfaceIndex != RAL_IFACE_INDEX) 417149871Sscottl return (ENXIO); 418136849Sscottl 419149871Sscottl return (usbd_lookup_id_by_uaa(ural_devs, sizeof(ural_devs), uaa)); 420149871Sscottl} 421136849Sscottl 422136849Sscottlstatic int 423136849Sscottlural_attach(device_t self) 424149871Sscottl{ 425149871Sscottl struct usb_attach_arg *uaa = device_get_ivars(self); 426136849Sscottl struct ural_softc *sc = device_get_softc(self); 427149871Sscottl struct ieee80211com *ic = &sc->sc_ic; 428136849Sscottl uint8_t iface_index; 429136849Sscottl int error; 430136849Sscottl 431136849Sscottl device_set_usb_desc(self); 432136849Sscottl sc->sc_udev = uaa->device; 433149871Sscottl sc->sc_dev = self; 434149871Sscottl 435136849Sscottl mtx_init(&sc->sc_mtx, device_get_nameunit(self), 436149871Sscottl MTX_NETWORK_LOCK, MTX_DEF); 437149871Sscottl mbufq_init(&sc->sc_snd, ifqmaxlen); 438136849Sscottl 439136849Sscottl iface_index = RAL_IFACE_INDEX; 440136849Sscottl error = usbd_transfer_setup(uaa->device, 441136849Sscottl &iface_index, sc->sc_xfer, ural_config, 442136849Sscottl URAL_N_TRANSFER, sc, &sc->sc_mtx); 443136849Sscottl if (error) { 444136849Sscottl device_printf(self, "could not allocate USB transfers, " 445136849Sscottl "err=%s\n", usbd_errstr(error)); 446136849Sscottl goto detach; 447136849Sscottl } 448136849Sscottl 449136849Sscottl RAL_LOCK(sc); 450136849Sscottl /* retrieve RT2570 rev. no */ 451136849Sscottl sc->asic_rev = ural_read(sc, RAL_MAC_CSR0); 452136849Sscottl 453149871Sscottl /* retrieve MAC address and various other things from EEPROM */ 454149871Sscottl ural_read_eeprom(sc); 455149871Sscottl RAL_UNLOCK(sc); 456136849Sscottl 457149871Sscottl device_printf(self, "MAC/BBP RT2570 (rev 0x%02x), RF %s\n", 458136849Sscottl sc->asic_rev, ural_get_rf(sc->rf_rev)); 459136849Sscottl 460136849Sscottl ic->ic_softc = sc; 461136849Sscottl ic->ic_name = device_get_nameunit(self); 462136849Sscottl ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 463136849Sscottl 464149871Sscottl /* set device capabilities */ 465149871Sscottl ic->ic_caps = 466149871Sscottl IEEE80211_C_STA /* station mode supported */ 467149871Sscottl | IEEE80211_C_IBSS /* IBSS mode supported */ 468136849Sscottl | IEEE80211_C_MONITOR /* monitor mode supported */ 469190809Sdelphij | IEEE80211_C_HOSTAP /* HostAp mode supported */ 470149871Sscottl | IEEE80211_C_TXPMGT /* tx power management */ 471136849Sscottl | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 472136849Sscottl | IEEE80211_C_SHSLOT /* short slot time supported */ 473136849Sscottl | IEEE80211_C_BGSCAN /* bg scanning supported */ 474149871Sscottl | IEEE80211_C_WPA /* 802.11i */ 475149871Sscottl ; 476190809Sdelphij 477149871Sscottl ural_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans, 478136849Sscottl ic->ic_channels); 479136849Sscottl 480136849Sscottl ieee80211_ifattach(ic); 481136849Sscottl ic->ic_update_promisc = ural_update_promisc; 482149871Sscottl ic->ic_raw_xmit = ural_raw_xmit; 483149871Sscottl ic->ic_scan_start = ural_scan_start; 484149871Sscottl ic->ic_scan_end = ural_scan_end; 485149871Sscottl ic->ic_getradiocaps = ural_getradiocaps; 486136849Sscottl ic->ic_set_channel = ural_set_channel; 487149871Sscottl ic->ic_parent = ural_parent; 488149871Sscottl ic->ic_transmit = ural_transmit; 489190809Sdelphij ic->ic_vap_create = ural_vap_create; 490149871Sscottl ic->ic_vap_delete = ural_vap_delete; 491136849Sscottl 492136849Sscottl ieee80211_radiotap_attach(ic, 493136849Sscottl &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), 494136849Sscottl RAL_TX_RADIOTAP_PRESENT, 495136849Sscottl &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), 496149871Sscottl RAL_RX_RADIOTAP_PRESENT); 497149871Sscottl 498190809Sdelphij if (bootverbose) 499149871Sscottl ieee80211_announce(ic); 500136849Sscottl 501136849Sscottl return (0); 502149871Sscottl 503149871Sscottldetach: 504190809Sdelphij ural_detach(self); 505149871Sscottl return (ENXIO); /* failure */ 506136849Sscottl} 507136849Sscottl 508136849Sscottlstatic int 509136849Sscottlural_detach(device_t self) 510136849Sscottl{ 511149871Sscottl struct ural_softc *sc = device_get_softc(self); 512149871Sscottl struct ieee80211com *ic = &sc->sc_ic; 513190809Sdelphij 514149871Sscottl /* prevent further ioctls */ 515136849Sscottl RAL_LOCK(sc); 516149871Sscottl sc->sc_detached = 1; 517149871Sscottl RAL_UNLOCK(sc); 518149871Sscottl 519190809Sdelphij /* stop all USB transfers */ 520149871Sscottl usbd_transfer_unsetup(sc->sc_xfer, URAL_N_TRANSFER); 521136849Sscottl 522136849Sscottl /* free TX list, if any */ 523136849Sscottl RAL_LOCK(sc); 524149871Sscottl ural_unsetup_tx_list(sc); 525136849Sscottl RAL_UNLOCK(sc); 526149871Sscottl 527149871Sscottl if (ic->ic_softc == sc) 528149871Sscottl ieee80211_ifdetach(ic); 529149871Sscottl mbufq_drain(&sc->sc_snd); 530149871Sscottl mtx_destroy(&sc->sc_mtx); 531149871Sscottl 532149871Sscottl return (0); 533149871Sscottl} 534190809Sdelphij 535149871Sscottlstatic usb_error_t 536136849Sscottlural_do_request(struct ural_softc *sc, 537136849Sscottl struct usb_device_request *req, void *data) 538136849Sscottl{ 539190809Sdelphij usb_error_t err; 540149871Sscottl int ntries = 10; 541149871Sscottl 542149871Sscottl while (ntries--) { 543149871Sscottl err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx, 544190809Sdelphij req, data, 0, NULL, 250 /* ms */); 545149871Sscottl if (err == 0) 546136849Sscottl break; 547149871Sscottl 548149871Sscottl DPRINTFN(1, "Control request failed, %s (retrying)\n", 549149871Sscottl usbd_errstr(err)); 550149871Sscottl if (ural_pause(sc, hz / 100)) 551190809Sdelphij break; 552149871Sscottl } 553149871Sscottl return (err); 554149871Sscottl} 555149871Sscottl 556149871Sscottlstatic struct ieee80211vap * 557190809Sdelphijural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 558149871Sscottl enum ieee80211_opmode opmode, int flags, 559149871Sscottl const uint8_t bssid[IEEE80211_ADDR_LEN], 560149871Sscottl const uint8_t mac[IEEE80211_ADDR_LEN]) 561136849Sscottl{ 562190809Sdelphij struct ural_softc *sc = ic->ic_softc; 563149871Sscottl struct ural_vap *uvp; 564136849Sscottl struct ieee80211vap *vap; 565136849Sscottl 566136849Sscottl if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 567136849Sscottl return NULL; 568190809Sdelphij uvp = malloc(sizeof(struct ural_vap), M_80211_VAP, M_WAITOK | M_ZERO); 569149871Sscottl vap = &uvp->vap; 570136849Sscottl /* enable s/w bmiss handling for sta mode */ 571149871Sscottl 572149871Sscottl if (ieee80211_vap_setup(ic, vap, name, unit, opmode, 573149871Sscottl flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) { 574149871Sscottl /* out of memory */ 575190809Sdelphij free(uvp, M_80211_VAP); 576149871Sscottl return (NULL); 577136849Sscottl } 578136849Sscottl 579136849Sscottl /* override state transition machine */ 580149871Sscottl uvp->newstate = vap->iv_newstate; 581149871Sscottl vap->iv_newstate = ural_newstate; 582136849Sscottl 583149871Sscottl usb_callout_init_mtx(&uvp->ratectl_ch, &sc->sc_mtx, 0); 584149871Sscottl TASK_INIT(&uvp->ratectl_task, 0, ural_ratectl_task, uvp); 585149871Sscottl ieee80211_ratectl_init(vap); 586136849Sscottl ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */); 587149871Sscottl 588149871Sscottl /* complete setup */ 589149871Sscottl ieee80211_vap_attach(vap, ieee80211_media_change, 590149871Sscottl ieee80211_media_status, mac); 591136849Sscottl ic->ic_opmode = opmode; 592136849Sscottl return vap; 593136849Sscottl} 594190809Sdelphij 595149871Sscottlstatic void 596136849Sscottlural_vap_delete(struct ieee80211vap *vap) 597136849Sscottl{ 598149871Sscottl struct ural_vap *uvp = URAL_VAP(vap); 599149871Sscottl struct ieee80211com *ic = vap->iv_ic; 600149871Sscottl 601190809Sdelphij usb_callout_drain(&uvp->ratectl_ch); 602149871Sscottl ieee80211_draintask(ic, &uvp->ratectl_task); 603136849Sscottl ieee80211_ratectl_deinit(vap); 604136849Sscottl ieee80211_vap_detach(vap); 605136849Sscottl free(uvp, M_80211_VAP); 606136849Sscottl} 607149871Sscottl 608149871Sscottlstatic void 609136849Sscottlural_tx_free(struct ural_tx_data *data, int txerr) 610149871Sscottl{ 611149871Sscottl struct ural_softc *sc = data->sc; 612149871Sscottl 613136849Sscottl if (data->m != NULL) { 614149871Sscottl ieee80211_tx_complete(data->ni, data->m, txerr); 615149871Sscottl data->m = NULL; 616149871Sscottl data->ni = NULL; 617136849Sscottl } 618149871Sscottl STAILQ_INSERT_TAIL(&sc->tx_free, data, next); 619149871Sscottl sc->tx_nfree++; 620149871Sscottl} 621136849Sscottl 622149871Sscottlstatic void 623149871Sscottlural_setup_tx_list(struct ural_softc *sc) 624149871Sscottl{ 625136849Sscottl struct ural_tx_data *data; 626136849Sscottl int i; 627136849Sscottl 628190809Sdelphij sc->tx_nfree = 0; 629149871Sscottl STAILQ_INIT(&sc->tx_q); 630136849Sscottl STAILQ_INIT(&sc->tx_free); 631136849Sscottl 632149871Sscottl for (i = 0; i < RAL_TX_LIST_COUNT; i++) { 633149871Sscottl data = &sc->tx_data[i]; 634149871Sscottl 635149871Sscottl data->sc = sc; 636190809Sdelphij STAILQ_INSERT_TAIL(&sc->tx_free, data, next); 637149871Sscottl sc->tx_nfree++; 638136849Sscottl } 639149871Sscottl} 640136849Sscottl 641136849Sscottlstatic void 642149871Sscottlural_unsetup_tx_list(struct ural_softc *sc) 643149871Sscottl{ 644149871Sscottl struct ural_tx_data *data; 645149871Sscottl int i; 646149871Sscottl 647149871Sscottl /* make sure any subsequent use of the queues will fail */ 648149871Sscottl sc->tx_nfree = 0; 649149871Sscottl STAILQ_INIT(&sc->tx_q); 650149871Sscottl STAILQ_INIT(&sc->tx_free); 651149871Sscottl 652149871Sscottl /* free up all node references and mbufs */ 653149871Sscottl for (i = 0; i < RAL_TX_LIST_COUNT; i++) { 654149871Sscottl data = &sc->tx_data[i]; 655149871Sscottl 656149871Sscottl if (data->m != NULL) { 657149871Sscottl m_freem(data->m); 658149871Sscottl data->m = NULL; 659149871Sscottl } 660149871Sscottl if (data->ni != NULL) { 661149871Sscottl ieee80211_free_node(data->ni); 662149871Sscottl data->ni = NULL; 663149871Sscottl } 664149871Sscottl } 665149871Sscottl} 666149871Sscottl 667149871Sscottlstatic int 668149871Sscottlural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 669149871Sscottl{ 670136849Sscottl struct ural_vap *uvp = URAL_VAP(vap); 671149871Sscottl struct ieee80211com *ic = vap->iv_ic; 672136849Sscottl struct ural_softc *sc = ic->ic_softc; 673149871Sscottl const struct ieee80211_txparam *tp; 674136849Sscottl struct ieee80211_node *ni; 675149871Sscottl struct mbuf *m; 676149871Sscottl 677149871Sscottl DPRINTF("%s -> %s\n", 678149871Sscottl ieee80211_state_name[vap->iv_state], 679149871Sscottl ieee80211_state_name[nstate]); 680149871Sscottl 681149871Sscottl IEEE80211_UNLOCK(ic); 682149871Sscottl RAL_LOCK(sc); 683190809Sdelphij usb_callout_stop(&uvp->ratectl_ch); 684149871Sscottl 685136849Sscottl switch (nstate) { 686136849Sscottl case IEEE80211_S_INIT: 687136849Sscottl if (vap->iv_state == IEEE80211_S_RUN) { 688190809Sdelphij /* abort TSF synchronization */ 689149871Sscottl ural_write(sc, RAL_TXRX_CSR19, 0); 690136849Sscottl 691149871Sscottl /* force tx led to stop blinking */ 692149871Sscottl ural_write(sc, RAL_MAC_CSR20, 0); 693190809Sdelphij } 694149871Sscottl break; 695149871Sscottl 696149871Sscottl case IEEE80211_S_RUN: 697149871Sscottl ni = ieee80211_ref_node(vap->iv_bss); 698149871Sscottl 699149871Sscottl if (vap->iv_opmode != IEEE80211_M_MONITOR) { 700190809Sdelphij if (ic->ic_bsschan == IEEE80211_CHAN_ANYC) 701149871Sscottl goto fail; 702149871Sscottl 703149871Sscottl ural_update_slot(sc); 704149871Sscottl ural_set_txpreamble(sc); 705149871Sscottl ural_set_basicrates(sc, ic->ic_bsschan); 706190809Sdelphij IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); 707149871Sscottl ural_set_bssid(sc, sc->sc_bssid); 708149871Sscottl } 709149871Sscottl 710136849Sscottl if (vap->iv_opmode == IEEE80211_M_HOSTAP || 711190809Sdelphij vap->iv_opmode == IEEE80211_M_IBSS) { 712149871Sscottl m = ieee80211_beacon_alloc(ni); 713149871Sscottl if (m == NULL) { 714136849Sscottl device_printf(sc->sc_dev, 715136849Sscottl "could not allocate beacon\n"); 716136849Sscottl goto fail; 717149871Sscottl } 718190809Sdelphij ieee80211_ref_node(ni); 719149871Sscottl if (ural_tx_bcn(sc, m, ni) != 0) { 720149871Sscottl device_printf(sc->sc_dev, 721149871Sscottl "could not send beacon\n"); 722149871Sscottl goto fail; 723149871Sscottl } 724190809Sdelphij } 725149871Sscottl 726136849Sscottl /* make tx led blink on tx (controlled by ASIC) */ 727136849Sscottl ural_write(sc, RAL_MAC_CSR20, 1); 728136849Sscottl 729136849Sscottl if (vap->iv_opmode != IEEE80211_M_MONITOR) 730149871Sscottl ural_enable_tsf_sync(sc); 731149871Sscottl else 732190809Sdelphij ural_enable_tsf(sc); 733149871Sscottl 734136849Sscottl /* enable automatic rate adaptation */ 735136849Sscottl /* XXX should use ic_bsschan but not valid until after newstate call below */ 736190809Sdelphij tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; 737149871Sscottl if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) 738136849Sscottl ural_ratectl_start(sc, ni); 739136849Sscottl ieee80211_free_node(ni); 740136849Sscottl break; 741136849Sscottl 742136849Sscottl default: 743136849Sscottl break; 744136849Sscottl } 745136849Sscottl RAL_UNLOCK(sc); 746136849Sscottl IEEE80211_LOCK(ic); 747136849Sscottl return (uvp->newstate(vap, nstate, arg)); 748149871Sscottl 749149871Sscottlfail: 750149871Sscottl RAL_UNLOCK(sc); 751269617Sjhb IEEE80211_LOCK(ic); 752269617Sjhb ieee80211_free_node(ni); 753149871Sscottl return (-1); 754149871Sscottl} 755149871Sscottl 756149871Sscottlstatic void 757149871Sscottlural_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) 758149871Sscottl{ 759149871Sscottl struct ural_softc *sc = usbd_xfer_softc(xfer); 760149871Sscottl struct ieee80211vap *vap; 761149871Sscottl struct ural_tx_data *data; 762190809Sdelphij struct mbuf *m; 763149871Sscottl struct usb_page_cache *pc; 764149871Sscottl int len; 765149871Sscottl 766149871Sscottl usbd_xfer_status(xfer, &len, NULL, NULL, NULL); 767190809Sdelphij 768149871Sscottl switch (USB_GET_STATE(xfer)) { 769149871Sscottl case USB_ST_TRANSFERRED: 770149871Sscottl DPRINTFN(11, "transfer complete, %d bytes\n", len); 771149871Sscottl 772149871Sscottl /* free resources */ 773149871Sscottl data = usbd_xfer_get_priv(xfer); 774149871Sscottl ural_tx_free(data, 0); 775149871Sscottl usbd_xfer_set_priv(xfer, NULL); 776190809Sdelphij 777149871Sscottl /* FALLTHROUGH */ 778149871Sscottl case USB_ST_SETUP: 779149871Sscottltr_setup: 780149871Sscottl data = STAILQ_FIRST(&sc->tx_q); 781149871Sscottl if (data) { 782149871Sscottl STAILQ_REMOVE_HEAD(&sc->tx_q, next); 783149871Sscottl m = data->m; 784149871Sscottl 785149871Sscottl if (m->m_pkthdr.len > (int)(RAL_FRAME_SIZE + RAL_TX_DESC_SIZE)) { 786149871Sscottl DPRINTFN(0, "data overflow, %u bytes\n", 787136849Sscottl m->m_pkthdr.len); 788149871Sscottl m->m_pkthdr.len = (RAL_FRAME_SIZE + RAL_TX_DESC_SIZE); 789149871Sscottl } 790149871Sscottl pc = usbd_xfer_get_frame(xfer, 0); 791149871Sscottl usbd_copy_in(pc, 0, &data->desc, RAL_TX_DESC_SIZE); 792190809Sdelphij usbd_m_copy_in(pc, RAL_TX_DESC_SIZE, m, 0, 793149871Sscottl m->m_pkthdr.len); 794149871Sscottl 795149871Sscottl vap = data->ni->ni_vap; 796149871Sscottl if (ieee80211_radiotap_active_vap(vap)) { 797149871Sscottl struct ural_tx_radiotap_header *tap = &sc->sc_txtap; 798149871Sscottl 799149871Sscottl tap->wt_flags = 0; 800149871Sscottl tap->wt_rate = data->rate; 801149871Sscottl tap->wt_antenna = sc->tx_ant; 802149871Sscottl 803149871Sscottl ieee80211_radiotap_tx(vap, m); 804190809Sdelphij } 805149871Sscottl 806149871Sscottl /* xfer length needs to be a multiple of two! */ 807149871Sscottl len = (RAL_TX_DESC_SIZE + m->m_pkthdr.len + 1) & ~1; 808136849Sscottl if ((len % 64) == 0) 809149871Sscottl len += 2; 810149871Sscottl 811190809Sdelphij DPRINTFN(11, "sending frame len=%u xferlen=%u\n", 812149871Sscottl m->m_pkthdr.len, len); 813149871Sscottl 814149871Sscottl usbd_xfer_set_frame_len(xfer, 0, len); 815136849Sscottl usbd_xfer_set_priv(xfer, data); 816136849Sscottl 817149871Sscottl usbd_transfer_submit(xfer); 818149871Sscottl } 819136849Sscottl ural_start(sc); 820149871Sscottl break; 821149871Sscottl 822136849Sscottl default: /* Error */ 823136849Sscottl DPRINTFN(11, "transfer error, %s\n", 824149871Sscottl usbd_errstr(error)); 825136849Sscottl 826136849Sscottl data = usbd_xfer_get_priv(xfer); 827136849Sscottl if (data != NULL) { 828136849Sscottl ural_tx_free(data, error); 829136849Sscottl usbd_xfer_set_priv(xfer, NULL); 830136849Sscottl } 831136849Sscottl 832136849Sscottl if (error == USB_ERR_STALLED) { 833149871Sscottl /* try to clear stall first */ 834136849Sscottl usbd_xfer_set_stall(xfer); 835136849Sscottl goto tr_setup; 836136849Sscottl } 837136849Sscottl if (error == USB_ERR_TIMEOUT) 838136849Sscottl device_printf(sc->sc_dev, "device timeout\n"); 839149871Sscottl break; 840136849Sscottl } 841136849Sscottl} 842136849Sscottl 843136849Sscottlstatic void 844149871Sscottlural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) 845136849Sscottl{ 846149871Sscottl struct ural_softc *sc = usbd_xfer_softc(xfer); 847136849Sscottl struct ieee80211com *ic = &sc->sc_ic; 848149871Sscottl struct ieee80211_node *ni; 849136849Sscottl struct mbuf *m = NULL; 850149871Sscottl struct usb_page_cache *pc; 851149871Sscottl uint32_t flags; 852149871Sscottl int8_t rssi = 0, nf = 0; 853136849Sscottl int len; 854149871Sscottl 855149871Sscottl usbd_xfer_status(xfer, &len, NULL, NULL, NULL); 856149871Sscottl 857190809Sdelphij switch (USB_GET_STATE(xfer)) { 858149871Sscottl case USB_ST_TRANSFERRED: 859149871Sscottl 860269617Sjhb DPRINTFN(15, "rx done, actlen=%d\n", len); 861149871Sscottl 862149871Sscottl if (len < (int)(RAL_RX_DESC_SIZE + IEEE80211_MIN_LEN)) { 863149871Sscottl DPRINTF("%s: xfer too short %d\n", 864149871Sscottl device_get_nameunit(sc->sc_dev), len); 865190809Sdelphij counter_u64_add(ic->ic_ierrors, 1); 866149871Sscottl goto tr_setup; 867149871Sscottl } 868149871Sscottl 869269617Sjhb len -= RAL_RX_DESC_SIZE; 870149871Sscottl /* rx descriptor is located at the end */ 871149871Sscottl pc = usbd_xfer_get_frame(xfer, 0); 872149871Sscottl usbd_copy_out(pc, len, &sc->sc_rx_desc, RAL_RX_DESC_SIZE); 873149871Sscottl 874149871Sscottl rssi = URAL_RSSI(sc->sc_rx_desc.rssi); 875136849Sscottl nf = RAL_NOISE_FLOOR; 876250460Seadler flags = le32toh(sc->sc_rx_desc.flags); 877250460Seadler if (flags & (RAL_RX_PHY_ERROR | RAL_RX_CRC_ERROR)) { 878149871Sscottl /* 879149871Sscottl * This should not happen since we did not 880149871Sscottl * request to receive those frames when we 881149871Sscottl * filled RAL_TXRX_CSR2: 882149871Sscottl */ 883149871Sscottl DPRINTFN(5, "PHY or CRC error\n"); 884190809Sdelphij counter_u64_add(ic->ic_ierrors, 1); 885149871Sscottl goto tr_setup; 886149871Sscottl } 887149871Sscottl 888190809Sdelphij m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 889149871Sscottl if (m == NULL) { 890149871Sscottl DPRINTF("could not allocate mbuf\n"); 891136849Sscottl counter_u64_add(ic->ic_ierrors, 1); 892136849Sscottl goto tr_setup; 893136849Sscottl } 894136849Sscottl usbd_copy_out(pc, 0, mtod(m, uint8_t *), len); 895149871Sscottl 896136849Sscottl /* finalize mbuf */ 897136849Sscottl m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff; 898149871Sscottl 899149871Sscottl if (ieee80211_radiotap_active(ic)) { 900149871Sscottl struct ural_rx_radiotap_header *tap = &sc->sc_rxtap; 901149871Sscottl 902190809Sdelphij /* XXX set once */ 903149871Sscottl tap->wr_flags = 0; 904136849Sscottl tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate, 905136849Sscottl (flags & RAL_RX_OFDM) ? 906149871Sscottl IEEE80211_T_OFDM : IEEE80211_T_CCK); 907149871Sscottl tap->wr_antenna = sc->rx_ant; 908136849Sscottl tap->wr_antsignal = nf + rssi; 909149871Sscottl tap->wr_antnoise = nf; 910149871Sscottl } 911149871Sscottl /* Strip trailing 802.11 MAC FCS. */ 912136849Sscottl m_adj(m, -IEEE80211_CRC_LEN); 913149871Sscottl 914136849Sscottl /* FALLTHROUGH */ 915149871Sscottl case USB_ST_SETUP: 916149871Sscottltr_setup: 917149871Sscottl usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); 918190809Sdelphij usbd_transfer_submit(xfer); 919149871Sscottl 920149871Sscottl /* 921136849Sscottl * At the end of a USB callback it is always safe to unlock 922136849Sscottl * the private mutex of a device! That is why we do the 923136849Sscottl * "ieee80211_input" here, and not some lines up! 924149871Sscottl */ 925149871Sscottl RAL_UNLOCK(sc); 926149871Sscottl if (m) { 927149871Sscottl ni = ieee80211_find_rxnode(ic, 928190809Sdelphij mtod(m, struct ieee80211_frame_min *)); 929149871Sscottl if (ni != NULL) { 930149871Sscottl (void) ieee80211_input(ni, m, rssi, nf); 931136849Sscottl ieee80211_free_node(ni); 932136849Sscottl } else 933149871Sscottl (void) ieee80211_input_all(ic, m, rssi, nf); 934149871Sscottl } 935136849Sscottl RAL_LOCK(sc); 936149871Sscottl ural_start(sc); 937149871Sscottl return; 938149871Sscottl 939149871Sscottl default: /* Error */ 940149871Sscottl if (error != USB_ERR_CANCELLED) { 941136849Sscottl /* try to clear stall first */ 942149871Sscottl usbd_xfer_set_stall(xfer); 943149871Sscottl goto tr_setup; 944149871Sscottl } 945250460Seadler return; 946149871Sscottl } 947149871Sscottl} 948149871Sscottl 949136849Sscottlstatic uint8_t 950136849Sscottlural_plcp_signal(int rate) 951136849Sscottl{ 952136849Sscottl switch (rate) { 953136849Sscottl /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 954136849Sscottl case 12: return 0xb; 955136849Sscottl case 18: return 0xf; 956136849Sscottl case 24: return 0xa; 957149871Sscottl case 36: return 0xe; 958149871Sscottl case 48: return 0x9; 959136849Sscottl case 72: return 0xd; 960136849Sscottl case 96: return 0x8; 961136849Sscottl case 108: return 0xc; 962136849Sscottl 963136849Sscottl /* CCK rates (NB: not IEEE std, device-specific) */ 964136849Sscottl case 2: return 0x0; 965136849Sscottl case 4: return 0x1; 966149871Sscottl case 11: return 0x2; 967136849Sscottl case 22: return 0x3; 968136849Sscottl } 969136849Sscottl return 0xff; /* XXX unsupported/unknown rate */ 970136849Sscottl} 971136849Sscottl 972136849Sscottlstatic void 973136849Sscottlural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc, 974136849Sscottl uint32_t flags, int len, int rate) 975136849Sscottl{ 976136849Sscottl struct ieee80211com *ic = &sc->sc_ic; 977136849Sscottl uint16_t plcp_length; 978136849Sscottl int remainder; 979136849Sscottl 980136849Sscottl desc->flags = htole32(flags); 981136849Sscottl desc->flags |= htole32(RAL_TX_NEWSEQ); 982136849Sscottl desc->flags |= htole32(len << 16); 983136849Sscottl 984136849Sscottl desc->wme = htole16(RAL_AIFSN(2) | RAL_LOGCWMIN(3) | RAL_LOGCWMAX(5)); 985136849Sscottl desc->wme |= htole16(RAL_IVOFFSET(sizeof (struct ieee80211_frame))); 986136849Sscottl 987136849Sscottl /* setup PLCP fields */ 988136849Sscottl desc->plcp_signal = ural_plcp_signal(rate); 989136849Sscottl desc->plcp_service = 4; 990149871Sscottl 991136849Sscottl len += IEEE80211_CRC_LEN; 992136849Sscottl if (ieee80211_rate2phytype(ic->ic_rt, rate) == IEEE80211_T_OFDM) { 993136849Sscottl desc->flags |= htole32(RAL_TX_OFDM); 994136849Sscottl 995136849Sscottl plcp_length = len & 0xfff; 996136849Sscottl desc->plcp_length_hi = plcp_length >> 6; 997136849Sscottl desc->plcp_length_lo = plcp_length & 0x3f; 998149871Sscottl } else { 999136849Sscottl if (rate == 0) 1000136849Sscottl rate = 2; /* avoid division by zero */ 1001136849Sscottl plcp_length = howmany(16 * len, rate); 1002149871Sscottl if (rate == 22) { 1003149871Sscottl remainder = (16 * len) % 22; 1004136849Sscottl if (remainder != 0 && remainder < 7) 1005149871Sscottl desc->plcp_service |= RAL_PLCP_LENGEXT; 1006149871Sscottl } 1007136849Sscottl desc->plcp_length_hi = plcp_length >> 8; 1008136849Sscottl desc->plcp_length_lo = plcp_length & 0xff; 1009136849Sscottl 1010136849Sscottl if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) 1011136849Sscottl desc->plcp_signal |= 0x08; 1012136849Sscottl } 1013149871Sscottl 1014149871Sscottl desc->iv = 0; 1015149871Sscottl desc->eiv = 0; 1016136849Sscottl} 1017136849Sscottl 1018136849Sscottl#define RAL_TX_TIMEOUT 5000 1019136849Sscottl 1020136849Sscottlstatic int 1021136849Sscottlural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) 1022136849Sscottl{ 1023136849Sscottl struct ieee80211vap *vap = ni->ni_vap; 1024136849Sscottl struct ieee80211com *ic = ni->ni_ic; 1025136849Sscottl const struct ieee80211_txparam *tp; 1026136849Sscottl struct ural_tx_data *data; 1027149871Sscottl 1028190809Sdelphij if (sc->tx_nfree == 0) { 1029190809Sdelphij m_freem(m0); 1030136849Sscottl ieee80211_free_node(ni); 1031136849Sscottl return (EIO); 1032136849Sscottl } 1033149871Sscottl if (ic->ic_bsschan == IEEE80211_CHAN_ANYC) { 1034149871Sscottl m_freem(m0); 1035136849Sscottl ieee80211_free_node(ni); 1036136849Sscottl return (ENXIO); 1037136849Sscottl } 1038149871Sscottl data = STAILQ_FIRST(&sc->tx_free); 1039136849Sscottl STAILQ_REMOVE_HEAD(&sc->tx_free, next); 1040136849Sscottl sc->tx_nfree--; 1041149871Sscottl tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; 1042149871Sscottl 1043149871Sscottl data->m = m0; 1044149871Sscottl data->ni = ni; 1045149871Sscottl data->rate = tp->mgmtrate; 1046149871Sscottl 1047136849Sscottl ural_setup_tx_desc(sc, &data->desc, 1048136849Sscottl RAL_TX_IFS_NEWBACKOFF | RAL_TX_TIMESTAMP, m0->m_pkthdr.len, 1049136849Sscottl tp->mgmtrate); 1050136849Sscottl 1051136849Sscottl DPRINTFN(10, "sending beacon frame len=%u rate=%u\n", 1052136849Sscottl m0->m_pkthdr.len, tp->mgmtrate); 1053136849Sscottl 1054136849Sscottl STAILQ_INSERT_TAIL(&sc->tx_q, data, next); 1055136849Sscottl usbd_transfer_start(sc->sc_xfer[URAL_BULK_WR]); 1056136849Sscottl 1057136849Sscottl return (0); 1058136849Sscottl} 1059136849Sscottl 1060136849Sscottlstatic int 1061136849Sscottlural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) 1062136849Sscottl{ 1063149871Sscottl const struct ieee80211_txparam *tp = ni->ni_txparms; 1064149871Sscottl struct ieee80211com *ic = ni->ni_ic; 1065149871Sscottl struct ural_tx_data *data; 1066136849Sscottl struct ieee80211_frame *wh; 1067136849Sscottl struct ieee80211_key *k; 1068136849Sscottl uint32_t flags; 1069136849Sscottl uint16_t dur; 1070136849Sscottl 1071136849Sscottl RAL_LOCK_ASSERT(sc, MA_OWNED); 1072136849Sscottl 1073136849Sscottl data = STAILQ_FIRST(&sc->tx_free); 1074136849Sscottl STAILQ_REMOVE_HEAD(&sc->tx_free, next); 1075136849Sscottl sc->tx_nfree--; 1076136849Sscottl 1077136849Sscottl wh = mtod(m0, struct ieee80211_frame *); 1078136849Sscottl if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 1079136849Sscottl k = ieee80211_crypto_encap(ni, m0); 1080136849Sscottl if (k == NULL) { 1081136849Sscottl m_freem(m0); 1082136849Sscottl return ENOBUFS; 1083136849Sscottl } 1084149871Sscottl wh = mtod(m0, struct ieee80211_frame *); 1085149871Sscottl } 1086149871Sscottl 1087136849Sscottl data->m = m0; 1088136849Sscottl data->ni = ni; 1089136849Sscottl data->rate = tp->mgmtrate; 1090136849Sscottl 1091136849Sscottl flags = 0; 1092136849Sscottl if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1093136849Sscottl flags |= RAL_TX_ACK; 1094190809Sdelphij 1095190809Sdelphij dur = ieee80211_ack_duration(ic->ic_rt, tp->mgmtrate, 1096190809Sdelphij ic->ic_flags & IEEE80211_F_SHPREAMBLE); 1097190809Sdelphij USETW(wh->i_dur, dur); 1098190809Sdelphij 1099190809Sdelphij /* tell hardware to add timestamp for probe responses */ 1100190809Sdelphij if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 1101190809Sdelphij IEEE80211_FC0_TYPE_MGT && 1102190809Sdelphij (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == 1103190809Sdelphij IEEE80211_FC0_SUBTYPE_PROBE_RESP) 1104190809Sdelphij flags |= RAL_TX_TIMESTAMP; 1105190809Sdelphij } 1106190809Sdelphij 1107190809Sdelphij ural_setup_tx_desc(sc, &data->desc, flags, m0->m_pkthdr.len, tp->mgmtrate); 1108190809Sdelphij 1109190809Sdelphij DPRINTFN(10, "sending mgt frame len=%u rate=%u\n", 1110190809Sdelphij m0->m_pkthdr.len, tp->mgmtrate); 1111190809Sdelphij 1112190809Sdelphij STAILQ_INSERT_TAIL(&sc->tx_q, data, next); 1113190809Sdelphij usbd_transfer_start(sc->sc_xfer[URAL_BULK_WR]); 1114190809Sdelphij 1115190809Sdelphij return 0; 1116190809Sdelphij} 1117190809Sdelphij 1118190809Sdelphijstatic int 1119190809Sdelphijural_sendprot(struct ural_softc *sc, 1120190809Sdelphij const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) 1121190809Sdelphij{ 1122190809Sdelphij struct ieee80211com *ic = ni->ni_ic; 1123190809Sdelphij struct ural_tx_data *data; 1124190809Sdelphij struct mbuf *mprot; 1125190809Sdelphij int protrate, flags; 1126190809Sdelphij 1127190809Sdelphij mprot = ieee80211_alloc_prot(ni, m, rate, prot); 1128190809Sdelphij if (mprot == NULL) { 1129190809Sdelphij if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); 1130190809Sdelphij device_printf(sc->sc_dev, 1131190809Sdelphij "could not allocate mbuf for protection mode %d\n", prot); 1132190809Sdelphij return ENOBUFS; 1133190809Sdelphij } 1134190809Sdelphij 1135190809Sdelphij protrate = ieee80211_ctl_rate(ic->ic_rt, rate); 1136190809Sdelphij flags = RAL_TX_RETRY(7); 1137190809Sdelphij if (prot == IEEE80211_PROT_RTSCTS) 1138190809Sdelphij flags |= RAL_TX_ACK; 1139190809Sdelphij 1140190809Sdelphij data = STAILQ_FIRST(&sc->tx_free); 1141190809Sdelphij STAILQ_REMOVE_HEAD(&sc->tx_free, next); 1142190809Sdelphij sc->tx_nfree--; 1143190809Sdelphij 1144190809Sdelphij data->m = mprot; 1145190809Sdelphij data->ni = ieee80211_ref_node(ni); 1146190809Sdelphij data->rate = protrate; 1147190809Sdelphij ural_setup_tx_desc(sc, &data->desc, flags, mprot->m_pkthdr.len, protrate); 1148190809Sdelphij 1149190809Sdelphij STAILQ_INSERT_TAIL(&sc->tx_q, data, next); 1150190809Sdelphij usbd_transfer_start(sc->sc_xfer[URAL_BULK_WR]); 1151190809Sdelphij 1152190809Sdelphij return 0; 1153190809Sdelphij} 1154190809Sdelphij 1155190809Sdelphijstatic int 1156190809Sdelphijural_tx_raw(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, 1157190809Sdelphij const struct ieee80211_bpf_params *params) 1158190809Sdelphij{ 1159190809Sdelphij struct ieee80211com *ic = ni->ni_ic; 1160190809Sdelphij struct ural_tx_data *data; 1161190809Sdelphij uint32_t flags; 1162190809Sdelphij int error; 1163190809Sdelphij int rate; 1164190809Sdelphij 1165190809Sdelphij RAL_LOCK_ASSERT(sc, MA_OWNED); 1166190809Sdelphij KASSERT(params != NULL, ("no raw xmit params")); 1167190809Sdelphij 1168190809Sdelphij rate = params->ibp_rate0; 1169190809Sdelphij if (!ieee80211_isratevalid(ic->ic_rt, rate)) { 1170190809Sdelphij m_freem(m0); 1171190809Sdelphij return EINVAL; 1172190809Sdelphij } 1173190809Sdelphij flags = 0; 1174190809Sdelphij if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) 1175190809Sdelphij flags |= RAL_TX_ACK; 1176190809Sdelphij if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) { 1177190809Sdelphij error = ural_sendprot(sc, m0, ni, 1178190809Sdelphij params->ibp_flags & IEEE80211_BPF_RTS ? 1179190809Sdelphij IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY, 1180190809Sdelphij rate); 1181190809Sdelphij if (error || sc->tx_nfree == 0) { 1182190809Sdelphij m_freem(m0); 1183190809Sdelphij return ENOBUFS; 1184190809Sdelphij } 1185190809Sdelphij flags |= RAL_TX_IFS_SIFS; 1186190809Sdelphij } 1187190809Sdelphij 1188190809Sdelphij data = STAILQ_FIRST(&sc->tx_free); 1189190809Sdelphij STAILQ_REMOVE_HEAD(&sc->tx_free, next); 1190190809Sdelphij sc->tx_nfree--; 1191190809Sdelphij 1192190809Sdelphij data->m = m0; 1193190809Sdelphij data->ni = ni; 1194190809Sdelphij data->rate = rate; 1195190809Sdelphij 1196190809Sdelphij /* XXX need to setup descriptor ourself */ 1197190809Sdelphij ural_setup_tx_desc(sc, &data->desc, flags, m0->m_pkthdr.len, rate); 1198190809Sdelphij 1199190809Sdelphij DPRINTFN(10, "sending raw frame len=%u rate=%u\n", 1200190809Sdelphij m0->m_pkthdr.len, rate); 1201190809Sdelphij 1202190809Sdelphij STAILQ_INSERT_TAIL(&sc->tx_q, data, next); 1203190809Sdelphij usbd_transfer_start(sc->sc_xfer[URAL_BULK_WR]); 1204190809Sdelphij 1205190809Sdelphij return 0; 1206190809Sdelphij} 1207190809Sdelphij 1208190809Sdelphijstatic int 1209190809Sdelphijural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) 1210190809Sdelphij{ 1211190809Sdelphij struct ieee80211vap *vap = ni->ni_vap; 1212190809Sdelphij struct ieee80211com *ic = ni->ni_ic; 1213190809Sdelphij struct ural_tx_data *data; 1214190809Sdelphij struct ieee80211_frame *wh; 1215136849Sscottl const struct ieee80211_txparam *tp = ni->ni_txparms; 1216136849Sscottl struct ieee80211_key *k; 1217149871Sscottl uint32_t flags = 0; 1218136849Sscottl uint16_t dur; 1219136849Sscottl int error, rate; 1220136849Sscottl 1221136849Sscottl RAL_LOCK_ASSERT(sc, MA_OWNED); 1222136849Sscottl 1223136849Sscottl wh = mtod(m0, struct ieee80211_frame *); 1224149871Sscottl 1225136849Sscottl if (m0->m_flags & M_EAPOL) 1226136849Sscottl rate = tp->mgmtrate; 1227136849Sscottl else if (IEEE80211_IS_MULTICAST(wh->i_addr1)) 1228136849Sscottl rate = tp->mcastrate; 1229136849Sscottl else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) 1230136849Sscottl rate = tp->ucastrate; 1231136849Sscottl else { 1232149871Sscottl (void) ieee80211_ratectl_rate(ni, NULL, 0); 1233149871Sscottl rate = ni->ni_txrate; 1234149871Sscottl } 1235149871Sscottl 1236149871Sscottl if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 1237149871Sscottl k = ieee80211_crypto_encap(ni, m0); 1238149871Sscottl if (k == NULL) { 1239149871Sscottl m_freem(m0); 1240149871Sscottl return ENOBUFS; 1241149871Sscottl } 1242149871Sscottl /* packet header may have moved, reset our local pointer */ 1243149871Sscottl wh = mtod(m0, struct ieee80211_frame *); 1244149871Sscottl } 1245149871Sscottl 1246149871Sscottl if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1247149871Sscottl int prot = IEEE80211_PROT_NONE; 1248136849Sscottl if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) 1249136849Sscottl prot = IEEE80211_PROT_RTSCTS; 1250136849Sscottl else if ((ic->ic_flags & IEEE80211_F_USEPROT) && 1251136849Sscottl ieee80211_rate2phytype(ic->ic_rt, rate) == IEEE80211_T_OFDM) 1252136849Sscottl prot = ic->ic_protmode; 1253136849Sscottl if (prot != IEEE80211_PROT_NONE) { 1254149871Sscottl error = ural_sendprot(sc, m0, ni, prot, rate); 1255136849Sscottl if (error || sc->tx_nfree == 0) { 1256136849Sscottl m_freem(m0); 1257136849Sscottl return ENOBUFS; 1258269617Sjhb } 1259269617Sjhb flags |= RAL_TX_IFS_SIFS; 1260269617Sjhb } 1261190809Sdelphij } 1262269617Sjhb 1263136849Sscottl data = STAILQ_FIRST(&sc->tx_free); 1264136849Sscottl STAILQ_REMOVE_HEAD(&sc->tx_free, next); 1265149871Sscottl sc->tx_nfree--; 1266136849Sscottl 1267136849Sscottl data->m = m0; 1268149871Sscottl data->ni = ni; 1269149871Sscottl data->rate = rate; 1270136849Sscottl 1271136849Sscottl if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1272136849Sscottl flags |= RAL_TX_ACK; 1273269617Sjhb flags |= RAL_TX_RETRY(7); 1274136849Sscottl 1275136849Sscottl dur = ieee80211_ack_duration(ic->ic_rt, rate, 1276136849Sscottl ic->ic_flags & IEEE80211_F_SHPREAMBLE); 1277136849Sscottl USETW(wh->i_dur, dur); 1278136849Sscottl } 1279136849Sscottl 1280136849Sscottl ural_setup_tx_desc(sc, &data->desc, flags, m0->m_pkthdr.len, rate); 1281232854Sscottl 1282149871Sscottl DPRINTFN(10, "sending data frame len=%u rate=%u\n", 1283149871Sscottl m0->m_pkthdr.len, rate); 1284149871Sscottl 1285149871Sscottl STAILQ_INSERT_TAIL(&sc->tx_q, data, next); 1286149871Sscottl usbd_transfer_start(sc->sc_xfer[URAL_BULK_WR]); 1287149871Sscottl 1288149871Sscottl return 0; 1289149871Sscottl} 1290149871Sscottl 1291149871Sscottlstatic int 1292269617Sjhbural_transmit(struct ieee80211com *ic, struct mbuf *m) 1293149871Sscottl{ 1294149871Sscottl struct ural_softc *sc = ic->ic_softc; 1295201758Smbr int error; 1296136849Sscottl 1297136849Sscottl RAL_LOCK(sc); 1298136849Sscottl if (!sc->sc_running) { 1299149871Sscottl RAL_UNLOCK(sc); 1300149871Sscottl return (ENXIO); 1301190809Sdelphij } 1302149871Sscottl error = mbufq_enqueue(&sc->sc_snd, m); 1303136849Sscottl if (error) { 1304136849Sscottl RAL_UNLOCK(sc); 1305136849Sscottl return (error); 1306136849Sscottl } 1307296135Sjhibbits ural_start(sc); 1308296135Sjhibbits RAL_UNLOCK(sc); 1309149871Sscottl 1310149871Sscottl return (0); 1311149871Sscottl} 1312190809Sdelphij 1313149871Sscottlstatic void 1314149871Sscottlural_start(struct ural_softc *sc) 1315136849Sscottl{ 1316149871Sscottl struct ieee80211_node *ni; 1317149871Sscottl struct mbuf *m; 1318190809Sdelphij 1319149871Sscottl RAL_LOCK_ASSERT(sc, MA_OWNED); 1320136849Sscottl 1321136849Sscottl if (sc->sc_running == 0) 1322136849Sscottl return; 1323149871Sscottl 1324136849Sscottl while (sc->tx_nfree >= RAL_TX_MINFREE && 1325149871Sscottl (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { 1326190809Sdelphij ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1327136849Sscottl if (ural_tx_data(sc, m, ni) != 0) { 1328136849Sscottl if_inc_counter(ni->ni_vap->iv_ifp, 1329136849Sscottl IFCOUNTER_OERRORS, 1); 1330136849Sscottl ieee80211_free_node(ni); 1331136849Sscottl break; 1332136849Sscottl } 1333136849Sscottl } 1334136849Sscottl} 1335136849Sscottl 1336149871Sscottlstatic void 1337149871Sscottlural_parent(struct ieee80211com *ic) 1338190809Sdelphij{ 1339149871Sscottl struct ural_softc *sc = ic->ic_softc; 1340149871Sscottl int startall = 0; 1341149871Sscottl 1342149871Sscottl RAL_LOCK(sc); 1343149871Sscottl if (sc->sc_detached) { 1344136849Sscottl RAL_UNLOCK(sc); 1345136849Sscottl return; 1346136849Sscottl } 1347136849Sscottl if (ic->ic_nrunning > 0) { 1348136849Sscottl if (sc->sc_running == 0) { 1349136849Sscottl ural_init(sc); 1350136849Sscottl startall = 1; 1351136849Sscottl } else 1352136849Sscottl ural_setpromisc(sc); 1353136849Sscottl } else if (sc->sc_running) 1354149871Sscottl ural_stop(sc); 1355149871Sscottl RAL_UNLOCK(sc); 1356149871Sscottl if (startall) 1357149871Sscottl ieee80211_start_all(ic); 1358149871Sscottl} 1359149871Sscottl 1360149871Sscottlstatic void 1361136849Sscottlural_set_testmode(struct ural_softc *sc) 1362149871Sscottl{ 1363149871Sscottl struct usb_device_request req; 1364149871Sscottl usb_error_t error; 1365136849Sscottl 1366149871Sscottl req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 1367149871Sscottl req.bRequest = RAL_VENDOR_REQUEST; 1368149871Sscottl USETW(req.wValue, 4); 1369149871Sscottl USETW(req.wIndex, 1); 1370149871Sscottl USETW(req.wLength, 0); 1371149871Sscottl 1372136849Sscottl error = ural_do_request(sc, &req, NULL); 1373136849Sscottl if (error != 0) { 1374149871Sscottl device_printf(sc->sc_dev, "could not set test mode: %s\n", 1375149871Sscottl usbd_errstr(error)); 1376149871Sscottl } 1377149871Sscottl} 1378149871Sscottl 1379149871Sscottlstatic void 1380149871Sscottlural_eeprom_read(struct ural_softc *sc, uint16_t addr, void *buf, int len) 1381149871Sscottl{ 1382149871Sscottl struct usb_device_request req; 1383149871Sscottl usb_error_t error; 1384149871Sscottl 1385149871Sscottl req.bmRequestType = UT_READ_VENDOR_DEVICE; 1386149871Sscottl req.bRequest = RAL_READ_EEPROM; 1387269617Sjhb USETW(req.wValue, 0); 1388149871Sscottl USETW(req.wIndex, addr); 1389136849Sscottl USETW(req.wLength, len); 1390136849Sscottl 1391136849Sscottl error = ural_do_request(sc, &req, buf); 1392149871Sscottl if (error != 0) { 1393149871Sscottl device_printf(sc->sc_dev, "could not read EEPROM: %s\n", 1394149871Sscottl usbd_errstr(error)); 1395149871Sscottl } 1396136862Sscottl} 1397136849Sscottl 1398136849Sscottlstatic uint16_t 1399136849Sscottlural_read(struct ural_softc *sc, uint16_t reg) 1400136849Sscottl{ 1401149871Sscottl struct usb_device_request req; 1402149871Sscottl usb_error_t error; 1403149871Sscottl uint16_t val; 1404149871Sscottl 1405149871Sscottl req.bmRequestType = UT_READ_VENDOR_DEVICE; 1406149871Sscottl req.bRequest = RAL_READ_MAC; 1407149871Sscottl USETW(req.wValue, 0); 1408149871Sscottl USETW(req.wIndex, reg); 1409149871Sscottl USETW(req.wLength, sizeof (uint16_t)); 1410136849Sscottl 1411136849Sscottl error = ural_do_request(sc, &req, &val); 1412136849Sscottl if (error != 0) { 1413136849Sscottl device_printf(sc->sc_dev, "could not read MAC register: %s\n", 1414136849Sscottl usbd_errstr(error)); 1415149871Sscottl return 0; 1416149871Sscottl } 1417136849Sscottl 1418136849Sscottl return le16toh(val); 1419149871Sscottl} 1420149871Sscottl 1421190809Sdelphijstatic void 1422149871Sscottlural_read_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len) 1423136849Sscottl{ 1424149871Sscottl struct usb_device_request req; 1425149871Sscottl usb_error_t error; 1426149871Sscottl 1427149871Sscottl req.bmRequestType = UT_READ_VENDOR_DEVICE; 1428190809Sdelphij req.bRequest = RAL_READ_MULTI_MAC; 1429149871Sscottl USETW(req.wValue, 0); 1430149871Sscottl USETW(req.wIndex, reg); 1431149871Sscottl USETW(req.wLength, len); 1432149871Sscottl 1433149871Sscottl error = ural_do_request(sc, &req, buf); 1434149871Sscottl if (error != 0) { 1435149871Sscottl device_printf(sc->sc_dev, "could not read MAC register: %s\n", 1436190809Sdelphij usbd_errstr(error)); 1437149871Sscottl } 1438149871Sscottl} 1439149871Sscottl 1440149871Sscottlstatic void 1441149871Sscottlural_write(struct ural_softc *sc, uint16_t reg, uint16_t val) 1442149871Sscottl{ 1443149871Sscottl struct usb_device_request req; 1444149871Sscottl usb_error_t error; 1445149871Sscottl 1446136849Sscottl req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 1447136849Sscottl req.bRequest = RAL_WRITE_MAC; 1448136849Sscottl USETW(req.wValue, val); 1449136849Sscottl USETW(req.wIndex, reg); 1450136849Sscottl USETW(req.wLength, 0); 1451136849Sscottl 1452136849Sscottl error = ural_do_request(sc, &req, NULL); 1453136849Sscottl if (error != 0) { 1454136849Sscottl device_printf(sc->sc_dev, "could not write MAC register: %s\n", 1455136849Sscottl usbd_errstr(error)); 1456136849Sscottl } 1457136849Sscottl} 1458136849Sscottl 1459136849Sscottlstatic void 1460136849Sscottlural_write_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len) 1461149871Sscottl{ 1462136849Sscottl struct usb_device_request req; 1463136849Sscottl usb_error_t error; 1464136849Sscottl 1465136849Sscottl req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 1466136849Sscottl req.bRequest = RAL_WRITE_MULTI_MAC; 1467136849Sscottl USETW(req.wValue, 0); 1468136849Sscottl USETW(req.wIndex, reg); 1469136849Sscottl USETW(req.wLength, len); 1470136849Sscottl 1471136849Sscottl error = ural_do_request(sc, &req, buf); 1472136849Sscottl if (error != 0) { 1473136849Sscottl device_printf(sc->sc_dev, "could not write MAC register: %s\n", 1474136849Sscottl usbd_errstr(error)); 1475136849Sscottl } 1476136849Sscottl} 1477136849Sscottl 1478136849Sscottlstatic void 1479136849Sscottlural_bbp_write(struct ural_softc *sc, uint8_t reg, uint8_t val) 1480136849Sscottl{ 1481136849Sscottl uint16_t tmp; 1482190809Sdelphij int ntries; 1483136849Sscottl 1484136849Sscottl for (ntries = 0; ntries < 100; ntries++) { 1485136849Sscottl if (!(ural_read(sc, RAL_PHY_CSR8) & RAL_BBP_BUSY)) 1486136849Sscottl break; 1487136849Sscottl if (ural_pause(sc, hz / 100)) 1488136849Sscottl break; 1489136849Sscottl } 1490136849Sscottl if (ntries == 100) { 1491136849Sscottl device_printf(sc->sc_dev, "could not write to BBP\n"); 1492149871Sscottl return; 1493136849Sscottl } 1494136849Sscottl 1495136849Sscottl tmp = reg << 8 | val; 1496136849Sscottl ural_write(sc, RAL_PHY_CSR7, tmp); 1497136849Sscottl} 1498136849Sscottl 1499149871Sscottlstatic uint8_t 1500149871Sscottlural_bbp_read(struct ural_softc *sc, uint8_t reg) 1501190809Sdelphij{ 1502149871Sscottl uint16_t val; 1503149871Sscottl int ntries; 1504136849Sscottl 1505136849Sscottl val = RAL_BBP_WRITE | reg << 8; 1506136849Sscottl ural_write(sc, RAL_PHY_CSR7, val); 1507136849Sscottl 1508149871Sscottl for (ntries = 0; ntries < 100; ntries++) { 1509149871Sscottl if (!(ural_read(sc, RAL_PHY_CSR8) & RAL_BBP_BUSY)) 1510190809Sdelphij break; 1511149871Sscottl if (ural_pause(sc, hz / 100)) 1512136849Sscottl break; 1513136849Sscottl } 1514136849Sscottl if (ntries == 100) { 1515136849Sscottl device_printf(sc->sc_dev, "could not read BBP\n"); 1516149871Sscottl return 0; 1517149871Sscottl } 1518190809Sdelphij 1519149871Sscottl return ural_read(sc, RAL_PHY_CSR7) & 0xff; 1520136849Sscottl} 1521136849Sscottl 1522149871Sscottlstatic void 1523149871Sscottlural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val) 1524149871Sscottl{ 1525149871Sscottl uint32_t tmp; 1526149871Sscottl int ntries; 1527149871Sscottl 1528149871Sscottl for (ntries = 0; ntries < 100; ntries++) { 1529149871Sscottl if (!(ural_read(sc, RAL_PHY_CSR10) & RAL_RF_LOBUSY)) 1530149871Sscottl break; 1531149871Sscottl if (ural_pause(sc, hz / 100)) 1532149871Sscottl break; 1533149871Sscottl } 1534149871Sscottl if (ntries == 100) { 1535149871Sscottl device_printf(sc->sc_dev, "could not write to RF\n"); 1536149871Sscottl return; 1537149871Sscottl } 1538149871Sscottl 1539149871Sscottl tmp = RAL_RF_BUSY | RAL_RF_20BIT | (val & 0xfffff) << 2 | (reg & 0x3); 1540149871Sscottl ural_write(sc, RAL_PHY_CSR9, tmp & 0xffff); 1541149871Sscottl ural_write(sc, RAL_PHY_CSR10, tmp >> 16); 1542136849Sscottl 1543136849Sscottl /* remember last written value in sc */ 1544149871Sscottl sc->rf_regs[reg] = val; 1545149871Sscottl 1546149871Sscottl DPRINTFN(15, "RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff); 1547149871Sscottl} 1548149871Sscottl 1549149871Sscottlstatic void 1550149871Sscottlural_scan_start(struct ieee80211com *ic) 1551149871Sscottl{ 1552149871Sscottl struct ural_softc *sc = ic->ic_softc; 1553136849Sscottl 1554136849Sscottl RAL_LOCK(sc); 1555136849Sscottl ural_write(sc, RAL_TXRX_CSR19, 0); 1556136849Sscottl ural_set_bssid(sc, ieee80211broadcastaddr); 1557136849Sscottl RAL_UNLOCK(sc); 1558149871Sscottl} 1559149871Sscottl 1560136849Sscottlstatic void 1561136849Sscottlural_scan_end(struct ieee80211com *ic) 1562136849Sscottl{ 1563136849Sscottl struct ural_softc *sc = ic->ic_softc; 1564136849Sscottl 1565136849Sscottl RAL_LOCK(sc); 1566136849Sscottl ural_enable_tsf_sync(sc); 1567136849Sscottl ural_set_bssid(sc, sc->sc_bssid); 1568136849Sscottl RAL_UNLOCK(sc); 1569136849Sscottl 1570136849Sscottl} 1571149871Sscottl 1572136849Sscottlstatic void 1573136849Sscottlural_getradiocaps(struct ieee80211com *ic, 1574149871Sscottl int maxchans, int *nchans, struct ieee80211_channel chans[]) 1575149871Sscottl{ 1576136849Sscottl struct ural_softc *sc = ic->ic_softc; 1577136849Sscottl uint8_t bands[IEEE80211_MODE_BYTES]; 1578136849Sscottl 1579136849Sscottl memset(bands, 0, sizeof(bands)); 1580149871Sscottl setbit(bands, IEEE80211_MODE_11B); 1581136849Sscottl setbit(bands, IEEE80211_MODE_11G); 1582136849Sscottl ieee80211_add_channels_default_2ghz(chans, maxchans, nchans, bands, 0); 1583136849Sscottl 1584136849Sscottl if (sc->rf_rev == RAL_RF_5222) { 1585149871Sscottl setbit(bands, IEEE80211_MODE_11A); 1586136849Sscottl ieee80211_add_channel_list_5ghz(chans, maxchans, nchans, 1587136849Sscottl ural_chan_5ghz, nitems(ural_chan_5ghz), bands, 0); 1588136849Sscottl } 1589136849Sscottl} 1590136849Sscottl 1591136849Sscottlstatic void 1592136849Sscottlural_set_channel(struct ieee80211com *ic) 1593136849Sscottl{ 1594136849Sscottl struct ural_softc *sc = ic->ic_softc; 1595136849Sscottl 1596149871Sscottl RAL_LOCK(sc); 1597136849Sscottl ural_set_chan(sc, ic->ic_curchan); 1598149871Sscottl RAL_UNLOCK(sc); 1599149871Sscottl} 1600136849Sscottl 1601149871Sscottlstatic void 1602136849Sscottlural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c) 1603136849Sscottl{ 1604149871Sscottl struct ieee80211com *ic = &sc->sc_ic; 1605136849Sscottl uint8_t power, tmp; 1606136849Sscottl int i, chan; 1607149871Sscottl 1608149871Sscottl chan = ieee80211_chan2ieee(ic, c); 1609136849Sscottl if (chan == 0 || chan == IEEE80211_CHAN_ANY) 1610136849Sscottl return; 1611136849Sscottl 1612136849Sscottl if (IEEE80211_IS_CHAN_2GHZ(c)) 1613136849Sscottl power = min(sc->txpow[chan - 1], 31); 1614136849Sscottl else 1615136849Sscottl power = 31; 1616136849Sscottl 1617136849Sscottl /* adjust txpower using ifconfig settings */ 1618136849Sscottl power -= (100 - ic->ic_txpowlimit) / 8; 1619136849Sscottl 1620136862Sscottl DPRINTFN(2, "setting channel to %u, txpower to %u\n", chan, power); 1621136849Sscottl 1622136849Sscottl switch (sc->rf_rev) { 1623136849Sscottl case RAL_RF_2522: 1624136849Sscottl ural_rf_write(sc, RAL_RF1, 0x00814); 1625136849Sscottl ural_rf_write(sc, RAL_RF2, ural_rf2522_r2[chan - 1]); 1626136849Sscottl ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040); 1627136849Sscottl break; 1628136849Sscottl 1629136849Sscottl case RAL_RF_2523: 1630136849Sscottl ural_rf_write(sc, RAL_RF1, 0x08804); 1631136849Sscottl ural_rf_write(sc, RAL_RF2, ural_rf2523_r2[chan - 1]); 1632136849Sscottl ural_rf_write(sc, RAL_RF3, power << 7 | 0x38044); 1633136849Sscottl ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286); 1634136849Sscottl break; 1635136849Sscottl 1636136849Sscottl case RAL_RF_2524: 1637149871Sscottl ural_rf_write(sc, RAL_RF1, 0x0c808); 1638136849Sscottl ural_rf_write(sc, RAL_RF2, ural_rf2524_r2[chan - 1]); 1639136849Sscottl ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040); 1640136849Sscottl ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286); 1641136849Sscottl break; 1642136849Sscottl 1643136849Sscottl case RAL_RF_2525: 1644149871Sscottl ural_rf_write(sc, RAL_RF1, 0x08808); 1645149871Sscottl ural_rf_write(sc, RAL_RF2, ural_rf2525_hi_r2[chan - 1]); 1646149871Sscottl ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044); 1647149871Sscottl ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286); 1648149871Sscottl 1649149871Sscottl ural_rf_write(sc, RAL_RF1, 0x08808); 1650149871Sscottl ural_rf_write(sc, RAL_RF2, ural_rf2525_r2[chan - 1]); 1651136849Sscottl ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044); 1652136849Sscottl ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286); 1653136849Sscottl break; 1654136849Sscottl 1655136849Sscottl case RAL_RF_2525E: 1656149871Sscottl ural_rf_write(sc, RAL_RF1, 0x08808); 1657136849Sscottl ural_rf_write(sc, RAL_RF2, ural_rf2525e_r2[chan - 1]); 1658149871Sscottl ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044); 1659149871Sscottl ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00286 : 0x00282); 1660136849Sscottl break; 1661136849Sscottl 1662136849Sscottl case RAL_RF_2526: 1663136849Sscottl ural_rf_write(sc, RAL_RF2, ural_rf2526_hi_r2[chan - 1]); 1664136849Sscottl ural_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381); 1665136849Sscottl ural_rf_write(sc, RAL_RF1, 0x08804); 1666136849Sscottl 1667149871Sscottl ural_rf_write(sc, RAL_RF2, ural_rf2526_r2[chan - 1]); 1668149871Sscottl ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044); 1669136849Sscottl ural_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381); 1670136849Sscottl break; 1671149871Sscottl 1672149871Sscottl /* dual-band RF */ 1673149871Sscottl case RAL_RF_5222: 1674149871Sscottl for (i = 0; ural_rf5222[i].chan != chan; i++); 1675149871Sscottl 1676149871Sscottl ural_rf_write(sc, RAL_RF1, ural_rf5222[i].r1); 1677149871Sscottl ural_rf_write(sc, RAL_RF2, ural_rf5222[i].r2); 1678149871Sscottl ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040); 1679149871Sscottl ural_rf_write(sc, RAL_RF4, ural_rf5222[i].r4); 1680136849Sscottl break; 1681149871Sscottl } 1682149871Sscottl 1683136849Sscottl if (ic->ic_opmode != IEEE80211_M_MONITOR && 1684149871Sscottl (ic->ic_flags & IEEE80211_F_SCAN) == 0) { 1685149871Sscottl /* set Japan filter bit for channel 14 */ 1686136849Sscottl tmp = ural_bbp_read(sc, 70); 1687136849Sscottl 1688136849Sscottl tmp &= ~RAL_JAPAN_FILTER; 1689136849Sscottl if (chan == 14) 1690136849Sscottl tmp |= RAL_JAPAN_FILTER; 1691136849Sscottl 1692136849Sscottl ural_bbp_write(sc, 70, tmp); 1693136849Sscottl 1694136849Sscottl /* clear CRC errors */ 1695149871Sscottl ural_read(sc, RAL_STA_CSR0); 1696136849Sscottl 1697136849Sscottl ural_pause(sc, hz / 100); 1698136849Sscottl ural_disable_rf_tune(sc); 1699136849Sscottl } 1700136849Sscottl 1701136849Sscottl /* XXX doesn't belong here */ 1702136849Sscottl /* update basic rate set */ 1703136849Sscottl ural_set_basicrates(sc, c); 1704136849Sscottl 1705136849Sscottl /* give the hardware some time to do the switchover */ 1706136849Sscottl ural_pause(sc, hz / 100); 1707149871Sscottl} 1708136849Sscottl 1709136849Sscottl/* 1710149871Sscottl * Disable RF auto-tuning. 1711149871Sscottl */ 1712190809Sdelphijstatic void 1713149871Sscottlural_disable_rf_tune(struct ural_softc *sc) 1714149871Sscottl{ 1715136849Sscottl uint32_t tmp; 1716136849Sscottl 1717149871Sscottl if (sc->rf_rev != RAL_RF_2523) { 1718149871Sscottl tmp = sc->rf_regs[RAL_RF1] & ~RAL_RF1_AUTOTUNE; 1719149871Sscottl ural_rf_write(sc, RAL_RF1, tmp); 1720190809Sdelphij } 1721149871Sscottl 1722149871Sscottl tmp = sc->rf_regs[RAL_RF3] & ~RAL_RF3_AUTOTUNE; 1723149871Sscottl ural_rf_write(sc, RAL_RF3, tmp); 1724136849Sscottl 1725136849Sscottl DPRINTFN(2, "disabling RF autotune\n"); 1726136849Sscottl} 1727136849Sscottl 1728136849Sscottl/* 1729136849Sscottl * Refer to IEEE Std 802.11-1999 pp. 123 for more information on TSF 1730136849Sscottl * synchronization. 1731136849Sscottl */ 1732136849Sscottlstatic void 1733136849Sscottlural_enable_tsf_sync(struct ural_softc *sc) 1734136849Sscottl{ 1735136849Sscottl struct ieee80211com *ic = &sc->sc_ic; 1736136849Sscottl struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 1737136849Sscottl uint16_t logcwmin, preload, tmp; 1738149871Sscottl 1739136849Sscottl /* first, disable TSF synchronization */ 1740136849Sscottl ural_write(sc, RAL_TXRX_CSR19, 0); 1741136849Sscottl 1742136849Sscottl tmp = (16 * vap->iv_bss->ni_intval) << 4; 1743136849Sscottl ural_write(sc, RAL_TXRX_CSR18, tmp); 1744136849Sscottl 1745136849Sscottl logcwmin = (ic->ic_opmode == IEEE80211_M_IBSS) ? 2 : 0; 1746136849Sscottl preload = (ic->ic_opmode == IEEE80211_M_IBSS) ? 320 : 6; 1747190809Sdelphij tmp = logcwmin << 12 | preload; 1748190809Sdelphij ural_write(sc, RAL_TXRX_CSR20, tmp); 1749190809Sdelphij 1750190809Sdelphij /* finally, enable TSF synchronization */ 1751190809Sdelphij tmp = RAL_ENABLE_TSF | RAL_ENABLE_TBCN; 1752190809Sdelphij if (ic->ic_opmode == IEEE80211_M_STA) 1753136849Sscottl tmp |= RAL_ENABLE_TSF_SYNC(1); 1754149871Sscottl else 1755149871Sscottl tmp |= RAL_ENABLE_TSF_SYNC(2) | RAL_ENABLE_BEACON_GENERATOR; 1756136849Sscottl ural_write(sc, RAL_TXRX_CSR19, tmp); 1757136849Sscottl 1758136849Sscottl DPRINTF("enabling TSF synchronization\n"); 1759136849Sscottl} 1760136849Sscottl 1761136849Sscottlstatic void 1762136849Sscottlural_enable_tsf(struct ural_softc *sc) 1763136849Sscottl{ 1764136849Sscottl /* first, disable TSF synchronization */ 1765136849Sscottl ural_write(sc, RAL_TXRX_CSR19, 0); 1766136849Sscottl ural_write(sc, RAL_TXRX_CSR19, RAL_ENABLE_TSF | RAL_ENABLE_TSF_SYNC(2)); 1767136849Sscottl} 1768136849Sscottl 1769136849Sscottl#define RAL_RXTX_TURNAROUND 5 /* us */ 1770136849Sscottlstatic void 1771136849Sscottlural_update_slot(struct ural_softc *sc) 1772136849Sscottl{ 1773136849Sscottl struct ieee80211com *ic = &sc->sc_ic; 1774136849Sscottl uint16_t slottime, sifs, eifs; 1775149871Sscottl 1776149871Sscottl slottime = IEEE80211_GET_SLOTTIME(ic); 1777149871Sscottl 1778149871Sscottl /* 1779136849Sscottl * These settings may sound a bit inconsistent but this is what the 1780149871Sscottl * reference driver does. 1781149871Sscottl */ 1782149871Sscottl if (ic->ic_curmode == IEEE80211_MODE_11B) { 1783149871Sscottl sifs = 16 - RAL_RXTX_TURNAROUND; 1784149871Sscottl eifs = 364; 1785149871Sscottl } else { 1786149871Sscottl sifs = 10 - RAL_RXTX_TURNAROUND; 1787149871Sscottl eifs = 64; 1788149871Sscottl } 1789149871Sscottl 1790149871Sscottl ural_write(sc, RAL_MAC_CSR10, slottime); 1791149871Sscottl ural_write(sc, RAL_MAC_CSR11, sifs); 1792149871Sscottl ural_write(sc, RAL_MAC_CSR12, eifs); 1793149871Sscottl} 1794136849Sscottl 1795149871Sscottlstatic void 1796149871Sscottlural_set_txpreamble(struct ural_softc *sc) 1797149871Sscottl{ 1798149871Sscottl struct ieee80211com *ic = &sc->sc_ic; 1799149871Sscottl uint16_t tmp; 1800149871Sscottl 1801149871Sscottl tmp = ural_read(sc, RAL_TXRX_CSR10); 1802149871Sscottl 1803149871Sscottl tmp &= ~RAL_SHORT_PREAMBLE; 1804149871Sscottl if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) 1805149871Sscottl tmp |= RAL_SHORT_PREAMBLE; 1806149871Sscottl 1807149871Sscottl ural_write(sc, RAL_TXRX_CSR10, tmp); 1808149871Sscottl} 1809149871Sscottl 1810149871Sscottlstatic void 1811149871Sscottlural_set_basicrates(struct ural_softc *sc, const struct ieee80211_channel *c) 1812149871Sscottl{ 1813149871Sscottl /* XXX wrong, take from rate set */ 1814149871Sscottl /* update basic rate set */ 1815149871Sscottl if (IEEE80211_IS_CHAN_5GHZ(c)) { 1816149871Sscottl /* 11a basic rates: 6, 12, 24Mbps */ 1817149871Sscottl ural_write(sc, RAL_TXRX_CSR11, 0x150); 1818149871Sscottl } else if (IEEE80211_IS_CHAN_ANYG(c)) { 1819149871Sscottl /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */ 1820136849Sscottl ural_write(sc, RAL_TXRX_CSR11, 0x15f); 1821149871Sscottl } else { 1822149871Sscottl /* 11b basic rates: 1, 2Mbps */ 1823149871Sscottl ural_write(sc, RAL_TXRX_CSR11, 0x3); 1824149871Sscottl } 1825149871Sscottl} 1826149871Sscottl 1827136849Sscottlstatic void 1828136849Sscottlural_set_bssid(struct ural_softc *sc, const uint8_t *bssid) 1829136849Sscottl{ 1830149871Sscottl uint16_t tmp; 1831136862Sscottl 1832136849Sscottl tmp = bssid[0] | bssid[1] << 8; 1833136849Sscottl ural_write(sc, RAL_MAC_CSR5, tmp); 1834149871Sscottl 1835136849Sscottl tmp = bssid[2] | bssid[3] << 8; 1836136849Sscottl ural_write(sc, RAL_MAC_CSR6, tmp); 1837136849Sscottl 1838136849Sscottl tmp = bssid[4] | bssid[5] << 8; 1839149871Sscottl ural_write(sc, RAL_MAC_CSR7, tmp); 1840149871Sscottl 1841136849Sscottl DPRINTF("setting BSSID to %6D\n", bssid, ":"); 1842136849Sscottl} 1843136849Sscottl 1844136849Sscottlstatic void 1845136849Sscottlural_set_macaddr(struct ural_softc *sc, const uint8_t *addr) 1846149871Sscottl{ 1847136849Sscottl uint16_t tmp; 1848149871Sscottl 1849149871Sscottl tmp = addr[0] | addr[1] << 8; 1850136849Sscottl ural_write(sc, RAL_MAC_CSR2, tmp); 1851136849Sscottl 1852136849Sscottl tmp = addr[2] | addr[3] << 8; 1853136849Sscottl ural_write(sc, RAL_MAC_CSR3, tmp); 1854136849Sscottl 1855149871Sscottl tmp = addr[4] | addr[5] << 8; 1856136849Sscottl ural_write(sc, RAL_MAC_CSR4, tmp); 1857149871Sscottl 1858149871Sscottl DPRINTF("setting MAC address to %6D\n", addr, ":"); 1859136849Sscottl} 1860149871Sscottl 1861149871Sscottlstatic void 1862136849Sscottlural_setpromisc(struct ural_softc *sc) 1863149871Sscottl{ 1864149871Sscottl uint32_t tmp; 1865136849Sscottl 1866136849Sscottl tmp = ural_read(sc, RAL_TXRX_CSR2); 1867136849Sscottl 1868149871Sscottl tmp &= ~RAL_DROP_NOT_TO_ME; 1869149871Sscottl if (sc->sc_ic.ic_promisc == 0) 1870149871Sscottl tmp |= RAL_DROP_NOT_TO_ME; 1871136849Sscottl 1872136849Sscottl ural_write(sc, RAL_TXRX_CSR2, tmp); 1873136849Sscottl 1874136849Sscottl DPRINTF("%s promiscuous mode\n", sc->sc_ic.ic_promisc ? 1875149871Sscottl "entering" : "leaving"); 1876149871Sscottl} 1877149871Sscottl 1878136849Sscottlstatic void 1879136849Sscottlural_update_promisc(struct ieee80211com *ic) 1880136849Sscottl{ 1881149871Sscottl struct ural_softc *sc = ic->ic_softc; 1882149871Sscottl 1883149871Sscottl RAL_LOCK(sc); 1884136849Sscottl if (sc->sc_running) 1885136849Sscottl ural_setpromisc(sc); 1886136849Sscottl RAL_UNLOCK(sc); 1887149871Sscottl} 1888149871Sscottl 1889136849Sscottlstatic const char * 1890136849Sscottlural_get_rf(int rev) 1891136849Sscottl{ 1892149871Sscottl switch (rev) { 1893149871Sscottl case RAL_RF_2522: return "RT2522"; 1894136849Sscottl case RAL_RF_2523: return "RT2523"; 1895136849Sscottl case RAL_RF_2524: return "RT2524"; 1896136849Sscottl case RAL_RF_2525: return "RT2525"; 1897136849Sscottl case RAL_RF_2525E: return "RT2525e"; 1898136849Sscottl case RAL_RF_2526: return "RT2526"; 1899136849Sscottl case RAL_RF_5222: return "RT5222"; 1900136849Sscottl default: return "unknown"; 1901136849Sscottl } 1902136849Sscottl} 1903136849Sscottl 1904136849Sscottlstatic void 1905136849Sscottlural_read_eeprom(struct ural_softc *sc) 1906136849Sscottl{ 1907136849Sscottl struct ieee80211com *ic = &sc->sc_ic; 1908136849Sscottl uint16_t val; 1909149871Sscottl 1910136849Sscottl ural_eeprom_read(sc, RAL_EEPROM_CONFIG0, &val, 2); 1911149871Sscottl val = le16toh(val); 1912136849Sscottl sc->rf_rev = (val >> 11) & 0x7; 1913136849Sscottl sc->hw_radio = (val >> 10) & 0x1; 1914149871Sscottl sc->led_mode = (val >> 6) & 0x7; 1915136849Sscottl sc->rx_ant = (val >> 4) & 0x3; 1916136849Sscottl sc->tx_ant = (val >> 2) & 0x3; 1917149871Sscottl sc->nb_ant = val & 0x3; 1918149871Sscottl 1919136849Sscottl /* read MAC address */ 1920136849Sscottl ural_eeprom_read(sc, RAL_EEPROM_ADDRESS, ic->ic_macaddr, 6); 1921136849Sscottl 1922136849Sscottl /* read default values for BBP registers */ 1923149871Sscottl ural_eeprom_read(sc, RAL_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16); 1924149871Sscottl 1925149871Sscottl /* read Tx power for all b/g channels */ 1926149871Sscottl ural_eeprom_read(sc, RAL_EEPROM_TXPOWER, sc->txpow, 14); 1927149871Sscottl} 1928149871Sscottl 1929149871Sscottlstatic int 1930149871Sscottlural_bbp_init(struct ural_softc *sc) 1931149871Sscottl{ 1932149871Sscottl int i, ntries; 1933149871Sscottl 1934149871Sscottl /* wait for BBP to be ready */ 1935149871Sscottl for (ntries = 0; ntries < 100; ntries++) { 1936149871Sscottl if (ural_bbp_read(sc, RAL_BBP_VERSION) != 0) 1937149871Sscottl break; 1938136849Sscottl if (ural_pause(sc, hz / 100)) 1939136849Sscottl break; 1940136849Sscottl } 1941136849Sscottl if (ntries == 100) { 1942136849Sscottl device_printf(sc->sc_dev, "timeout waiting for BBP\n"); 1943136849Sscottl return EIO; 1944136849Sscottl } 1945136849Sscottl 1946136849Sscottl /* initialize BBP registers to default values */ 1947136849Sscottl for (i = 0; i < nitems(ural_def_bbp); i++) 1948136849Sscottl ural_bbp_write(sc, ural_def_bbp[i].reg, ural_def_bbp[i].val); 1949136849Sscottl 1950136849Sscottl#if 0 1951136849Sscottl /* initialize BBP registers to values stored in EEPROM */ 1952136849Sscottl for (i = 0; i < 16; i++) { 1953136849Sscottl if (sc->bbp_prom[i].reg == 0xff) 1954136849Sscottl continue; 1955136849Sscottl ural_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val); 1956136849Sscottl } 1957136849Sscottl#endif 1958136849Sscottl 1959136849Sscottl return 0; 1960149871Sscottl} 1961149871Sscottl 1962136849Sscottlstatic void 1963136849Sscottlural_set_txantenna(struct ural_softc *sc, int antenna) 1964267368Sdelphij{ 1965136849Sscottl uint16_t tmp; 1966136849Sscottl uint8_t tx; 1967136849Sscottl 1968136849Sscottl tx = ural_bbp_read(sc, RAL_BBP_TX) & ~RAL_BBP_ANTMASK; 1969136849Sscottl if (antenna == 1) 1970136849Sscottl tx |= RAL_BBP_ANTA; 1971136849Sscottl else if (antenna == 2) 1972136849Sscottl tx |= RAL_BBP_ANTB; 1973136849Sscottl else 1974136849Sscottl tx |= RAL_BBP_DIVERSITY; 1975136849Sscottl 1976136849Sscottl /* need to force I/Q flip for RF 2525e, 2526 and 5222 */ 1977136849Sscottl if (sc->rf_rev == RAL_RF_2525E || sc->rf_rev == RAL_RF_2526 || 1978149871Sscottl sc->rf_rev == RAL_RF_5222) 1979136849Sscottl tx |= RAL_BBP_FLIPIQ; 1980136849Sscottl 1981136849Sscottl ural_bbp_write(sc, RAL_BBP_TX, tx); 1982136849Sscottl 1983136849Sscottl /* update values in PHY_CSR5 and PHY_CSR6 */ 1984269617Sjhb tmp = ural_read(sc, RAL_PHY_CSR5) & ~0x7; 1985136849Sscottl ural_write(sc, RAL_PHY_CSR5, tmp | (tx & 0x7)); 1986136849Sscottl 1987136849Sscottl tmp = ural_read(sc, RAL_PHY_CSR6) & ~0x7; 1988136849Sscottl ural_write(sc, RAL_PHY_CSR6, tmp | (tx & 0x7)); 1989136849Sscottl} 1990136849Sscottl 1991136849Sscottlstatic void 1992136849Sscottlural_set_rxantenna(struct ural_softc *sc, int antenna) 1993295790Sjhibbits{ 1994149871Sscottl uint8_t rx; 1995136849Sscottl 1996136849Sscottl rx = ural_bbp_read(sc, RAL_BBP_RX) & ~RAL_BBP_ANTMASK; 1997136849Sscottl if (antenna == 1) 1998136849Sscottl rx |= RAL_BBP_ANTA; 1999269617Sjhb else if (antenna == 2) 2000269617Sjhb rx |= RAL_BBP_ANTB; 2001190809Sdelphij else 2002149871Sscottl rx |= RAL_BBP_DIVERSITY; 2003136849Sscottl 2004136849Sscottl /* need to force no I/Q flip for RF 2525e and 2526 */ 2005136849Sscottl if (sc->rf_rev == RAL_RF_2525E || sc->rf_rev == RAL_RF_2526) 2006136849Sscottl rx &= ~RAL_BBP_FLIPIQ; 2007136849Sscottl 2008149871Sscottl ural_bbp_write(sc, RAL_BBP_RX, rx); 2009149871Sscottl} 2010149871Sscottl 2011149871Sscottlstatic void 2012136849Sscottlural_init(struct ural_softc *sc) 2013136849Sscottl{ 2014149871Sscottl struct ieee80211com *ic = &sc->sc_ic; 2015149871Sscottl struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 2016149871Sscottl uint16_t tmp; 2017136849Sscottl int i, ntries; 2018136849Sscottl 2019136849Sscottl RAL_LOCK_ASSERT(sc, MA_OWNED); 2020136849Sscottl 2021136849Sscottl ural_set_testmode(sc); 2022149871Sscottl ural_write(sc, 0x308, 0x00f0); /* XXX magic */ 2023149871Sscottl 2024136849Sscottl ural_stop(sc); 2025136849Sscottl 2026136849Sscottl /* initialize MAC registers to default values */ 2027136849Sscottl for (i = 0; i < nitems(ural_def_mac); i++) 2028136849Sscottl ural_write(sc, ural_def_mac[i].reg, ural_def_mac[i].val); 2029136849Sscottl 2030136849Sscottl /* wait for BBP and RF to wake up (this can take a long time!) */ 2031190809Sdelphij for (ntries = 0; ntries < 100; ntries++) { 2032269617Sjhb tmp = ural_read(sc, RAL_MAC_CSR17); 2033269617Sjhb if ((tmp & (RAL_BBP_AWAKE | RAL_RF_AWAKE)) == 2034190809Sdelphij (RAL_BBP_AWAKE | RAL_RF_AWAKE)) 2035136849Sscottl break; 2036136849Sscottl if (ural_pause(sc, hz / 100)) 2037136849Sscottl break; 2038136849Sscottl } 2039269617Sjhb if (ntries == 100) { 2040190809Sdelphij device_printf(sc->sc_dev, 2041149871Sscottl "timeout waiting for BBP/RF to wakeup\n"); 2042136849Sscottl goto fail; 2043269617Sjhb } 2044136849Sscottl 2045136849Sscottl /* we're ready! */ 2046136849Sscottl ural_write(sc, RAL_MAC_CSR1, RAL_HOST_READY); 2047136849Sscottl 2048136849Sscottl /* set basic rate set (will be updated later) */ 2049149871Sscottl ural_write(sc, RAL_TXRX_CSR11, 0x15f); 2050149871Sscottl 2051149871Sscottl if (ural_bbp_init(sc) != 0) 2052136849Sscottl goto fail; 2053136849Sscottl 2054269617Sjhb ural_set_chan(sc, ic->ic_curchan); 2055136849Sscottl 2056136849Sscottl /* clear statistic registers (STA_CSR0 to STA_CSR10) */ 2057136849Sscottl ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta); 2058269617Sjhb 2059136849Sscottl ural_set_txantenna(sc, sc->tx_ant); 2060136849Sscottl ural_set_rxantenna(sc, sc->rx_ant); 2061136849Sscottl 2062136849Sscottl ural_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); 2063136849Sscottl 2064136849Sscottl /* 2065136849Sscottl * Allocate Tx and Rx xfer queues. 2066136849Sscottl */ 2067136849Sscottl ural_setup_tx_list(sc); 2068190863Sdelphij 2069190810Sdelphij /* kick Rx */ 2070190810Sdelphij tmp = RAL_DROP_PHY | RAL_DROP_CRC; 2071139044Snjl if (ic->ic_opmode != IEEE80211_M_MONITOR) { 2072136849Sscottl tmp |= RAL_DROP_CTL | RAL_DROP_BAD_VERSION; 2073136849Sscottl if (ic->ic_opmode != IEEE80211_M_HOSTAP) 2074136849Sscottl tmp |= RAL_DROP_TODS; 2075136849Sscottl if (ic->ic_promisc == 0) 2076136849Sscottl tmp |= RAL_DROP_NOT_TO_ME; 2077136849Sscottl } 2078149871Sscottl ural_write(sc, RAL_TXRX_CSR2, tmp); 2079136849Sscottl 2080136849Sscottl sc->sc_running = 1; 2081136849Sscottl usbd_xfer_set_stall(sc->sc_xfer[URAL_BULK_WR]); 2082149871Sscottl usbd_transfer_start(sc->sc_xfer[URAL_BULK_RD]); 2083136849Sscottl return; 2084136849Sscottl 2085136849Sscottlfail: ural_stop(sc); 2086136849Sscottl} 2087136849Sscottl 2088136849Sscottlstatic void 2089136849Sscottlural_stop(struct ural_softc *sc) 2090136849Sscottl{ 2091269617Sjhb 2092269617Sjhb RAL_LOCK_ASSERT(sc, MA_OWNED); 2093269617Sjhb 2094269617Sjhb sc->sc_running = 0; 2095269617Sjhb 2096136849Sscottl /* 2097136849Sscottl * Drain all the transfers, if not already drained: 2098136849Sscottl */ 2099136849Sscottl RAL_UNLOCK(sc); 2100136849Sscottl usbd_transfer_drain(sc->sc_xfer[URAL_BULK_WR]); 2101136849Sscottl usbd_transfer_drain(sc->sc_xfer[URAL_BULK_RD]); 2102136849Sscottl RAL_LOCK(sc); 2103136849Sscottl 2104136849Sscottl ural_unsetup_tx_list(sc); 2105269617Sjhb 2106269617Sjhb /* disable Rx */ 2107269617Sjhb ural_write(sc, RAL_TXRX_CSR2, RAL_DISABLE_RX); 2108269617Sjhb /* reset ASIC and BBP (but won't reset MAC registers!) */ 2109269617Sjhb ural_write(sc, RAL_MAC_CSR1, RAL_RESET_ASIC | RAL_RESET_BBP); 2110269617Sjhb /* wait a little */ 2111269617Sjhb ural_pause(sc, hz / 10); 2112269617Sjhb ural_write(sc, RAL_MAC_CSR1, 0); 2113269617Sjhb /* wait a little */ 2114269617Sjhb ural_pause(sc, hz / 10); 2115269617Sjhb} 2116269617Sjhb 2117269617Sjhbstatic int 2118136849Sscottlural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2119149871Sscottl const struct ieee80211_bpf_params *params) 2120149871Sscottl{ 2121136849Sscottl struct ieee80211com *ic = ni->ni_ic; 2122136849Sscottl struct ural_softc *sc = ic->ic_softc; 2123136849Sscottl 2124136849Sscottl RAL_LOCK(sc); 2125136849Sscottl /* prevent management frames from being sent if we're not ready */ 2126136849Sscottl if (!sc->sc_running) { 2127136849Sscottl RAL_UNLOCK(sc); 2128136849Sscottl m_freem(m); 2129136849Sscottl return ENETDOWN; 2130136849Sscottl } 2131136849Sscottl if (sc->tx_nfree < RAL_TX_MINFREE) { 2132136849Sscottl RAL_UNLOCK(sc); 2133136849Sscottl m_freem(m); 2134136849Sscottl return EIO; 2135136849Sscottl } 2136136849Sscottl 2137136849Sscottl if (params == NULL) { 2138136849Sscottl /* 2139136849Sscottl * Legacy path; interpret frame contents to decide 2140136849Sscottl * precisely how to send the frame. 2141136849Sscottl */ 2142136849Sscottl if (ural_tx_mgt(sc, m, ni) != 0) 2143136849Sscottl goto bad; 2144136849Sscottl } else { 2145136849Sscottl /* 2146136849Sscottl * Caller supplied explicit parameters to use in 2147136849Sscottl * sending the frame. 2148136849Sscottl */ 2149136849Sscottl if (ural_tx_raw(sc, m, ni, params) != 0) 2150136849Sscottl goto bad; 2151136849Sscottl } 2152136849Sscottl RAL_UNLOCK(sc); 2153136849Sscottl return 0; 2154136849Sscottlbad: 2155136849Sscottl RAL_UNLOCK(sc); 2156136849Sscottl return EIO; /* XXX */ 2157136849Sscottl} 2158149871Sscottl 2159136849Sscottlstatic void 2160136849Sscottlural_ratectl_start(struct ural_softc *sc, struct ieee80211_node *ni) 2161136849Sscottl{ 2162136849Sscottl struct ieee80211vap *vap = ni->ni_vap; 2163136849Sscottl struct ural_vap *uvp = URAL_VAP(vap); 2164136849Sscottl 2165149871Sscottl /* clear statistic registers (STA_CSR0 to STA_CSR10) */ 2166149871Sscottl ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta); 2167149871Sscottl 2168136849Sscottl usb_callout_reset(&uvp->ratectl_ch, hz, ural_ratectl_timeout, uvp); 2169149871Sscottl} 2170269617Sjhb 2171149871Sscottlstatic void 2172269617Sjhbural_ratectl_timeout(void *arg) 2173149871Sscottl{ 2174149871Sscottl struct ural_vap *uvp = arg; 2175149871Sscottl struct ieee80211vap *vap = &uvp->vap; 2176149871Sscottl struct ieee80211com *ic = vap->iv_ic; 2177136849Sscottl 2178136849Sscottl ieee80211_runtask(ic, &uvp->ratectl_task); 2179136849Sscottl} 2180136849Sscottl 2181136849Sscottlstatic void 2182136849Sscottlural_ratectl_task(void *arg, int pending) 2183136849Sscottl{ 2184136849Sscottl struct ural_vap *uvp = arg; 2185136849Sscottl struct ieee80211vap *vap = &uvp->vap; 2186136849Sscottl struct ural_softc *sc = vap->iv_ic->ic_softc; 2187149871Sscottl struct ieee80211_ratectl_tx_stats *txs = &sc->sc_txs; 2188149871Sscottl int fail; 2189136849Sscottl 2190149871Sscottl RAL_LOCK(sc); 2191149871Sscottl /* read and clear statistic registers (STA_CSR0 to STA_CSR10) */ 2192149871Sscottl ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof(sc->sta)); 2193149871Sscottl 2194149871Sscottl txs->flags = IEEE80211_RATECTL_TX_STATS_RETRIES; 2195149871Sscottl txs->nsuccess = sc->sta[7] + /* TX ok w/o retry */ 2196149871Sscottl sc->sta[8]; /* TX ok w/ retry */ 2197149871Sscottl fail = sc->sta[9]; /* TX retry-fail count */ 2198136849Sscottl txs->nframes = txs->nsuccess + fail; 2199136849Sscottl /* XXX fail * maxretry */ 2200136849Sscottl txs->nretries = sc->sta[8] + fail; 2201136849Sscottl 2202136849Sscottl ieee80211_ratectl_tx_update(vap, txs); 2203149871Sscottl 2204149871Sscottl /* count TX retry-fail as Tx errors */ 2205136849Sscottl if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, fail); 2206149871Sscottl 2207136849Sscottl usb_callout_reset(&uvp->ratectl_ch, hz, ural_ratectl_timeout, uvp); 2208136849Sscottl RAL_UNLOCK(sc); 2209136849Sscottl} 2210136849Sscottl 2211136849Sscottlstatic int 2212136849Sscottlural_pause(struct ural_softc *sc, int timeout) 2213136849Sscottl{ 2214136849Sscottl 2215149871Sscottl usb_pause_mtx(&sc->sc_mtx, timeout); 2216149871Sscottl return (0); 2217149871Sscottl} 2218136849Sscottl