diff --git a/sys/contrib/dev/athnfw/athn-open-ar9271.bin b/sys/contrib/dev/athnfw/athn-open-ar9271.bin new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@ + * Copyright (c) 2008-2009 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Driver for Atheros 802.11a/g/n chipsets. + * Routines common to AR5008, AR9001 and AR9002 families. + */ + +// #include "bpfilter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#include +// #include +#include /* uintptr_t */ +#include + +#include + +#if NBPFILTER > 0 +#include +#endif +#include +#include + +#include +#include + +#include + + +#include +#include +#include +#include + +#include "athnreg.h" +#include "athnvar.h" + +#include "ar5008reg.h" +#include "ar5416reg.h" + +int ar5008_attach(struct athn_softc *); +int ar5008_read_eep_word(struct athn_softc *, uint32_t, uint16_t *); +int ar5008_read_rom(struct athn_softc *); +void ar5008_swap_rom(struct athn_softc *); +int ar5008_gpio_read(struct athn_softc *, int); +void ar5008_gpio_write(struct athn_softc *, int, int); +void ar5008_gpio_config_input(struct athn_softc *, int); +void ar5008_gpio_config_output(struct athn_softc *, int, int); +void ar5008_rfsilent_init(struct athn_softc *); +int ar5008_dma_alloc(struct athn_softc *); +void ar5008_dma_free(struct athn_softc *); +int ar5008_tx_alloc(struct athn_softc *); +void ar5008_tx_free(struct athn_softc *); +int ar5008_rx_alloc(struct athn_softc *); +void ar5008_rx_free(struct athn_softc *); +void ar5008_rx_enable(struct athn_softc *); +void ar5008_rx_radiotap(struct athn_softc *, struct mbuf *, + struct ar_rx_desc *); +int ar5008_ccmp_decap(struct athn_softc *, struct mbuf *, + struct ieee80211_node *); +void ar5008_rx_intr(struct athn_softc *); +int ar5008_tx_process(struct athn_softc *, int); +void ar5008_tx_intr(struct athn_softc *); +int ar5008_swba_intr(struct athn_softc *); +int ar5008_intr(struct athn_softc *); +int ar5008_ccmp_encap(struct mbuf *, u_int, struct ieee80211_key *); +// int ar5008_tx(struct athn_softc *, struct mbuf *, struct ieee80211_node *, +// int); +void ar5008_set_rf_mode(struct athn_softc *, struct ieee80211_channel *); +int ar5008_rf_bus_request(struct athn_softc *); +void ar5008_rf_bus_release(struct athn_softc *); +void ar5008_set_phy(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +void ar5008_set_delta_slope(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +void ar5008_enable_antenna_diversity(struct athn_softc *); +void ar5008_init_baseband(struct athn_softc *); +void ar5008_disable_phy(struct athn_softc *); +void ar5008_init_chains(struct athn_softc *); +void ar5008_set_rxchains(struct athn_softc *); +void ar5008_read_noisefloor(struct athn_softc *, int16_t *, int16_t *); +void ar5008_write_noisefloor(struct athn_softc *, int16_t *, int16_t *); +int ar5008_get_noisefloor(struct athn_softc *); +void ar5008_apply_noisefloor(struct athn_softc *); +void ar5008_bb_load_noisefloor(struct athn_softc *); +void ar5008_do_noisefloor_calib(struct athn_softc *); +void ar5008_init_noisefloor_calib(struct athn_softc *); +void ar5008_do_calib(struct athn_softc *); +void ar5008_next_calib(struct athn_softc *); +void ar5008_calib_iq(struct athn_softc *); +void ar5008_calib_adc_gain(struct athn_softc *); +void ar5008_calib_adc_dc_off(struct athn_softc *); +void ar5008_write_txpower(struct athn_softc *, int16_t *); +void ar5008_set_viterbi_mask(struct athn_softc *, int); +void ar5008_hw_init(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +uint8_t ar5008_get_vpd(uint8_t, const uint8_t *, const uint8_t *, int); +void ar5008_get_pdadcs(struct athn_softc *, uint8_t, struct athn_pier *, + struct athn_pier *, int, int, uint8_t, uint8_t *, uint8_t *); +void ar5008_get_lg_tpow(struct athn_softc *, struct ieee80211_channel *, + uint8_t, const struct ar_cal_target_power_leg *, int, uint8_t *); +void ar5008_get_ht_tpow(struct athn_softc *, struct ieee80211_channel *, + uint8_t, const struct ar_cal_target_power_ht *, int, uint8_t *); +void ar5008_set_noise_immunity_level(struct athn_softc *, int); +void ar5008_enable_ofdm_weak_signal(struct athn_softc *); +void ar5008_disable_ofdm_weak_signal(struct athn_softc *); +void ar5008_set_cck_weak_signal(struct athn_softc *, int); +void ar5008_set_firstep_level(struct athn_softc *, int); +void ar5008_set_spur_immunity_level(struct athn_softc *, int); + +/* Extern functions. */ +extern void athn_stop(struct ifnet *, int); +extern int athn_interpolate(int, int, int, int, int); +extern int athn_txtime(struct athn_softc *, int, int, u_int); +extern void athn_inc_tx_trigger_level(struct athn_softc *); +extern int athn_tx_pending(struct athn_softc *, int); +extern void athn_stop_tx_dma(struct athn_softc *, int); +extern void athn_get_delta_slope(uint32_t, uint32_t *, uint32_t *); +extern void athn_config_pcie(struct athn_softc *); +extern void athn_config_nonpcie(struct athn_softc *); +extern uint8_t athn_chan2fbin(struct ieee80211_channel *); +// extern uint8_t ar5416_get_rf_rev(struct athn_softc *); +void ar5416_reset_addac(struct athn_softc *, struct ieee80211_channel *); +void ar5416_rf_reset(struct athn_softc *, struct ieee80211_channel *); +void ar5416_reset_bb_gain(struct athn_softc *, struct ieee80211_channel *); +extern void ar9280_reset_rx_gain(struct athn_softc *, struct ieee80211_channel *); +extern void ar9280_reset_tx_gain(struct athn_softc *, struct ieee80211_channel *); + +uint8_t +ar5416_reverse_bits(uint8_t v, int nbits) +{ + KASSERT(nbits <= 8, "ar5416_reverse_bits"); + v = ((v >> 1) & 0x55) | ((v & 0x55) << 1); + v = ((v >> 2) & 0x33) | ((v & 0x33) << 2); + v = ((v >> 4) & 0x0f) | ((v & 0x0f) << 4); + return (v >> (8 - nbits)); +} + +uint8_t +ar5416_get_rf_rev(struct athn_softc *sc) +{ + uint8_t rev, reg; + int i; + + /* Allow access to analog chips. */ + AR_WRITE(sc, AR_PHY(0), 0x00000007); + + AR_WRITE(sc, AR_PHY(0x36), 0x00007058); + for (i = 0; i < 8; i++) + AR_WRITE(sc, AR_PHY(0x20), 0x00010000); + reg = (AR_READ(sc, AR_PHY(256)) >> 24) & 0xff; + reg = (reg & 0xf0) >> 4 | (reg & 0x0f) << 4; + + rev = ar5416_reverse_bits(reg, 8); + if ((rev & AR_RADIO_SREV_MAJOR) == 0) + rev = AR_RAD5133_SREV_MAJOR; + return (rev); +} + + +int +ar5008_attach(struct athn_softc *sc) +{ + struct athn_ops *ops = &sc->ops; + struct ieee80211com *ic = &sc->sc_ic; + struct ar_base_eep_header *base; + uint8_t eep_ver, kc_entries_log; + int error; + + /* Set callbacks for AR5008, AR9001 and AR9002 families. */ + ops->gpio_read = ar5008_gpio_read; + ops->gpio_write = ar5008_gpio_write; + ops->gpio_config_input = ar5008_gpio_config_input; + ops->gpio_config_output = ar5008_gpio_config_output; + ops->rfsilent_init = ar5008_rfsilent_init; + + // Not needed + // ops->dma_alloc = ar5008_dma_alloc; + // ops->dma_free = ar5008_dma_free; + // ops->rx_enable = ar5008_rx_enable; + // ops->intr = ar5008_intr; + // ops->tx = ar5008_tx; + + ops->set_rf_mode = ar5008_set_rf_mode; + ops->rf_bus_request = ar5008_rf_bus_request; + ops->rf_bus_release = ar5008_rf_bus_release; + ops->set_phy = ar5008_set_phy; + ops->set_delta_slope = ar5008_set_delta_slope; + ops->enable_antenna_diversity = ar5008_enable_antenna_diversity; + ops->init_baseband = ar5008_init_baseband; + ops->disable_phy = ar5008_disable_phy; + ops->set_rxchains = ar5008_set_rxchains; + ops->noisefloor_calib = ar5008_do_noisefloor_calib; + ops->init_noisefloor_calib = ar5008_init_noisefloor_calib; + ops->get_noisefloor = ar5008_get_noisefloor; + ops->apply_noisefloor = ar5008_apply_noisefloor; + ops->do_calib = ar5008_do_calib; + ops->next_calib = ar5008_next_calib; + ops->hw_init = ar5008_hw_init; + + ops->set_noise_immunity_level = ar5008_set_noise_immunity_level; + ops->enable_ofdm_weak_signal = ar5008_enable_ofdm_weak_signal; + ops->disable_ofdm_weak_signal = ar5008_disable_ofdm_weak_signal; + ops->set_cck_weak_signal = ar5008_set_cck_weak_signal; + ops->set_firstep_level = ar5008_set_firstep_level; + ops->set_spur_immunity_level = ar5008_set_spur_immunity_level; + + /* Set MAC registers offsets. */ + sc->obs_off = AR_OBS; + sc->gpio_input_en_off = AR_GPIO_INPUT_EN_VAL; + + athn_config_nonpcie(sc); + + + /* Read entire ROM content in memory. */ + if ((error = ar5008_read_rom(sc)) != 0) { + // printf("%s: could not read ROM\n", sc->sc_dev.dv_xname); + return (error); + } + + /* Get RF revision. */ + sc->rf_rev = ar5416_get_rf_rev(sc); + + base = sc->eep; + eep_ver = (base->version >> 12) & 0xf; + sc->eep_rev = (base->version & 0xfff); + if (eep_ver != AR_EEP_VER || sc->eep_rev == 0) { + // printf("%s: unsupported ROM version %d.%d\n", + // sc->sc_dev.dv_xname, eep_ver, sc->eep_rev); + return (EINVAL); + } + + if (base->opCapFlags & AR_OPFLAGS_11A) { + sc->flags |= ATHN_FLAG_11A; + if ((base->opCapFlags & AR_OPFLAGS_11N_5G20) == 0) + sc->flags |= ATHN_FLAG_11N; +#ifdef notyet + if ((base->opCapFlags & AR_OPFLAGS_11N_5G40) == 0) + sc->flags |= ATHN_FLAG_11N; +#endif + } + if (base->opCapFlags & AR_OPFLAGS_11G) { + sc->flags |= ATHN_FLAG_11G; + if ((base->opCapFlags & AR_OPFLAGS_11N_2G20) == 0) + sc->flags |= ATHN_FLAG_11N; +#ifdef notyet + if ((base->opCapFlags & AR_OPFLAGS_11N_2G40) == 0) + sc->flags |= ATHN_FLAG_11N; +#endif + } + + IEEE80211_ADDR_COPY(ic->ic_macaddr, base->macAddr); + + /* Check if we have a hardware radio switch. */ + if (base->rfSilent & AR_EEP_RFSILENT_ENABLED) { + sc->flags |= ATHN_FLAG_RFSILENT; + /* Get GPIO pin used by hardware radio switch. */ + sc->rfsilent_pin = MS(base->rfSilent, + AR_EEP_RFSILENT_GPIO_SEL); + /* Get polarity of hardware radio switch. */ + if (base->rfSilent & AR_EEP_RFSILENT_POLARITY) + sc->flags |= ATHN_FLAG_RFSILENT_REVERSED; + } + + /* Get the number of HW key cache entries. */ + kc_entries_log = MS(base->deviceCap, AR_EEP_DEVCAP_KC_ENTRIES); + sc->kc_entries = (kc_entries_log != 0) ? + 1 << kc_entries_log : AR_KEYTABLE_SIZE; + if (sc->kc_entries > AR_KEYTABLE_SIZE) + sc->kc_entries = AR_KEYTABLE_SIZE; + + sc->txchainmask = base->txMask; + if (sc->mac_ver == AR_SREV_VERSION_5416_PCI && + !(base->opCapFlags & AR_OPFLAGS_11A)) { + /* For single-band AR5416 PCI, use GPIO pin 0. */ + sc->rxchainmask = ar5008_gpio_read(sc, 0) ? 0x5 : 0x7; + } else + sc->rxchainmask = base->rxMask; + + ops->setup(sc); + return (0); +} + +/* + * Read 16-bit word from ROM. + */ +int +ar5008_read_eep_word(struct athn_softc *sc, uint32_t addr, uint16_t *val) +{ + uint32_t reg; + int ntries; + + DELAY(1000); + reg = AR_READ(sc, AR_EEPROM_OFFSET(addr)); + for (ntries = 0; ntries < 1000; ntries++) { + reg = AR_READ(sc, AR_EEPROM_STATUS_DATA); + if (!(reg & (AR_EEPROM_STATUS_DATA_BUSY | + AR_EEPROM_STATUS_DATA_PROT_ACCESS))) { + *val = MS(reg, AR_EEPROM_STATUS_DATA_VAL); + return (0); + } + DELAY(1000); + } + *val = 0xffff; + return (ETIMEDOUT); +} + +int +ar5008_read_rom(struct athn_softc *sc) +{ + uint32_t addr, end; + uint16_t magic, sum, *eep; + int need_swap = 0; + int error; + + /* Determine ROM endianness. */ + error = ar5008_read_eep_word(sc, AR_EEPROM_MAGIC_OFFSET, &magic); + if (error != 0) + return (error); + if (magic != AR_EEPROM_MAGIC) { + if (magic != __bswap16(AR_EEPROM_MAGIC)) { + DPRINTF(("invalid ROM magic 0x%x != 0x%x\n", + magic, AR_EEPROM_MAGIC)); + return (EIO); + } + DPRINTF(("non-native ROM endianness\n")); + need_swap = 1; + } + + /* Allocate space to store ROM in host memory. */ + sc->eep = malloc(sc->eep_size, M_DEVBUF, M_NOWAIT); + if (sc->eep == NULL) + return (ENOMEM); + + /* Read entire ROM and compute checksum. */ + sum = 0; + eep = sc->eep; + end = sc->eep_base + sc->eep_size / sizeof(uint16_t); + for (addr = sc->eep_base; addr < end; addr++, eep++) { + if ((error = ar5008_read_eep_word(sc, addr, eep)) != 0) { + DPRINTF(("could not read ROM at 0x%x\n", addr)); + return (error); + } + if (need_swap) + *eep = __bswap16(*eep); + sum ^= *eep; + } + if (sum != 0xffff) { + // printf("%s: bad ROM checksum 0x%04x\n", + // sc->sc_dev.dv_xname, sum); + return (EIO); + } + if (need_swap) + ar5008_swap_rom(sc); + + return (0); +} + +void +ar5008_swap_rom(struct athn_softc *sc) +{ + struct ar_base_eep_header *base = sc->eep; + + /* Swap common fields first. */ + base->length = __bswap16(base->length); + base->version = __bswap16(base->version); + base->regDmn[0] = __bswap16(base->regDmn[0]); + base->regDmn[1] = __bswap16(base->regDmn[1]); + base->rfSilent = __bswap16(base->rfSilent); + base->blueToothOptions = __bswap16(base->blueToothOptions); + base->deviceCap = __bswap16(base->deviceCap); + + /* Swap device-dependent fields. */ + sc->ops.swap_rom(sc); +} + +/* + * Access to General Purpose Input/Output ports. + */ +int +ar5008_gpio_read(struct athn_softc *sc, int pin) +{ + KASSERT(pin < sc->ngpiopins, "Panic in ar5008_gpio_read"); + if ((sc->flags & ATHN_FLAG_USB) && !AR_SREV_9271(sc)) + return (!((AR_READ(sc, AR7010_GPIO_IN) >> pin) & 1)); + return ((AR_READ(sc, AR_GPIO_IN_OUT) >> (sc->ngpiopins + pin)) & 1); +} + +void +ar5008_gpio_write(struct athn_softc *sc, int pin, int set) +{ + uint32_t reg; + + KASSERT(pin < sc->ngpiopins, "Panic in ar5008_gpio_write"); + + if (sc->flags & ATHN_FLAG_USB) + set = !set; /* AR9271/AR7010 is reversed. */ + + if ((sc->flags & ATHN_FLAG_USB) && !AR_SREV_9271(sc)) { + /* Special case for AR7010. */ + reg = AR_READ(sc, AR7010_GPIO_OUT); + if (set) + reg |= 1 << pin; + else + reg &= ~(1 << pin); + AR_WRITE(sc, AR7010_GPIO_OUT, reg); + } else { + reg = AR_READ(sc, AR_GPIO_IN_OUT); + if (set) + reg |= 1 << pin; + else + reg &= ~(1 << pin); + AR_WRITE(sc, AR_GPIO_IN_OUT, reg); + } + AR_WRITE_BARRIER(sc); +} + +void +ar5008_gpio_config_input(struct athn_softc *sc, int pin) +{ + uint32_t reg; + + if ((sc->flags & ATHN_FLAG_USB) && !AR_SREV_9271(sc)) { + /* Special case for AR7010. */ + AR_SETBITS(sc, AR7010_GPIO_OE, 1 << pin); + } else { + reg = AR_READ(sc, AR_GPIO_OE_OUT); + reg &= ~(AR_GPIO_OE_OUT_DRV_M << (pin * 2)); + reg |= AR_GPIO_OE_OUT_DRV_NO << (pin * 2); + AR_WRITE(sc, AR_GPIO_OE_OUT, reg); + } + AR_WRITE_BARRIER(sc); +} + +void +ar5008_gpio_config_output(struct athn_softc *sc, int pin, int type) +{ + uint32_t reg; + int mux, off; + + if ((sc->flags & ATHN_FLAG_USB) && !AR_SREV_9271(sc)) { + /* Special case for AR7010. */ + AR_CLRBITS(sc, AR7010_GPIO_OE, 1 << pin); + AR_WRITE_BARRIER(sc); + return; + } + mux = pin / 6; + off = pin % 6; + + reg = AR_READ(sc, AR_GPIO_OUTPUT_MUX(mux)); + if (!AR_SREV_9280_20_OR_LATER(sc) && mux == 0) + reg = (reg & ~0x1f0) | (reg & 0x1f0) << 1; + reg &= ~(0x1f << (off * 5)); + reg |= (type & 0x1f) << (off * 5); + AR_WRITE(sc, AR_GPIO_OUTPUT_MUX(mux), reg); + + reg = AR_READ(sc, AR_GPIO_OE_OUT); + reg &= ~(AR_GPIO_OE_OUT_DRV_M << (pin * 2)); + reg |= AR_GPIO_OE_OUT_DRV_ALL << (pin * 2); + AR_WRITE(sc, AR_GPIO_OE_OUT, reg); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_rfsilent_init(struct athn_softc *sc) +{ + uint32_t reg; + + /* Configure hardware radio switch. */ + AR_SETBITS(sc, AR_GPIO_INPUT_EN_VAL, AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); + reg = AR_READ(sc, AR_GPIO_INPUT_MUX2); + reg = RW(reg, AR_GPIO_INPUT_MUX2_RFSILENT, 0); + AR_WRITE(sc, AR_GPIO_INPUT_MUX2, reg); + ar5008_gpio_config_input(sc, sc->rfsilent_pin); + AR_SETBITS(sc, AR_PHY_TEST, AR_PHY_TEST_RFSILENT_BB); + if (!(sc->flags & ATHN_FLAG_RFSILENT_REVERSED)) { + AR_SETBITS(sc, AR_GPIO_INTR_POL, + AR_GPIO_INTR_POL_PIN(sc->rfsilent_pin)); + } + AR_WRITE_BARRIER(sc); +} +// Not needed +// int +// ar5008_dma_alloc(struct athn_softc *sc) +// { +// int error; + +// error = ar5008_tx_alloc(sc); +// if (error != 0) +// return (error); + +// error = ar5008_rx_alloc(sc); +// if (error != 0) +// return (error); + +// return (0); +// } + +// void +// ar5008_dma_free(struct athn_softc *sc) +// { +// ar5008_tx_free(sc); +// ar5008_rx_free(sc); +// } + +// int +// ar5008_tx_alloc(struct athn_softc *sc) +// { +// struct athn_tx_buf *bf; +// bus_size_t size; +// int error, nsegs, i; + +// /* +// * Allocate a pool of Tx descriptors shared between all Tx queues. +// */ +// size = ATHN_NTXBUFS * AR5008_MAX_SCATTER * sizeof(struct ar_tx_desc); + +// error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, +// BUS_DMA_NOWAIT, &sc->map); +// if (error != 0) +// goto fail; + +// error = bus_dmamem_alloc(sc->sc_dmat, size, 4, 0, &sc->seg, 1, +// &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO); +// if (error != 0) +// goto fail; + +// error = bus_dmamem_map(sc->sc_dmat, &sc->seg, 1, size, +// (caddr_t *)&sc->descs, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); +// if (error != 0) +// goto fail; + +// error = bus_dmamap_load_raw(sc->sc_dmat, sc->map, &sc->seg, 1, size, +// BUS_DMA_NOWAIT); +// if (error != 0) +// goto fail; + +// SIMPLEQ_INIT(&sc->txbufs); +// for (i = 0; i < ATHN_NTXBUFS; i++) { +// bf = &sc->txpool[i]; + +// error = bus_dmamap_create(sc->sc_dmat, ATHN_TXBUFSZ, +// AR5008_MAX_SCATTER, ATHN_TXBUFSZ, 0, BUS_DMA_NOWAIT, +// &bf->bf_map); +// if (error != 0) { +// printf("%s: could not create Tx buf DMA map\n", +// sc->sc_dev.dv_xname); +// goto fail; +// } + +// bf->bf_descs = +// &((struct ar_tx_desc *)sc->descs)[i * AR5008_MAX_SCATTER]; +// bf->bf_daddr = sc->map->dm_segs[0].ds_addr + +// i * AR5008_MAX_SCATTER * sizeof(struct ar_tx_desc); + +// SIMPLEQ_INSERT_TAIL(&sc->txbufs, bf, bf_list); +// } +// return (0); +// fail: +// ar5008_tx_free(sc); +// return (error); +// } + +// void +// ar5008_tx_free(struct athn_softc *sc) +// { +// struct athn_tx_buf *bf; +// int i; + +// for (i = 0; i < ATHN_NTXBUFS; i++) { +// bf = &sc->txpool[i]; + +// if (bf->bf_map != NULL) +// bus_dmamap_destroy(sc->sc_dmat, bf->bf_map); +// } +// /* Free Tx descriptors. */ +// if (sc->map != NULL) { +// if (sc->descs != NULL) { +// bus_dmamap_unload(sc->sc_dmat, sc->map); +// bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->descs, +// ATHN_NTXBUFS * AR5008_MAX_SCATTER * +// sizeof(struct ar_tx_desc)); +// bus_dmamem_free(sc->sc_dmat, &sc->seg, 1); +// } +// bus_dmamap_destroy(sc->sc_dmat, sc->map); +// } +// } + +// int +// ar5008_rx_alloc(struct athn_softc *sc) +// { +// struct athn_rxq *rxq = &sc->rxq[0]; +// struct athn_rx_buf *bf; +// struct ar_rx_desc *ds; +// bus_size_t size; +// int error, nsegs, i; + +// rxq->bf = mallocarray(ATHN_NRXBUFS, sizeof(*bf), M_DEVBUF, +// M_NOWAIT | M_ZERO); +// if (rxq->bf == NULL) +// return (ENOMEM); + +// size = ATHN_NRXBUFS * sizeof(struct ar_rx_desc); + +// error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, +// BUS_DMA_NOWAIT, &rxq->map); +// if (error != 0) +// goto fail; + +// error = bus_dmamem_alloc(sc->sc_dmat, size, 0, 0, &rxq->seg, 1, +// &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO); +// if (error != 0) +// goto fail; + +// error = bus_dmamem_map(sc->sc_dmat, &rxq->seg, 1, size, +// (caddr_t *)&rxq->descs, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); +// if (error != 0) +// goto fail; + +// error = bus_dmamap_load_raw(sc->sc_dmat, rxq->map, &rxq->seg, 1, +// size, BUS_DMA_NOWAIT); +// if (error != 0) +// goto fail; + +// for (i = 0; i < ATHN_NRXBUFS; i++) { +// bf = &rxq->bf[i]; +// ds = &((struct ar_rx_desc *)rxq->descs)[i]; + +// error = bus_dmamap_create(sc->sc_dmat, ATHN_RXBUFSZ, 1, +// ATHN_RXBUFSZ, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, +// &bf->bf_map); +// if (error != 0) { +// printf("%s: could not create Rx buf DMA map\n", +// sc->sc_dev.dv_xname); +// goto fail; +// } +// /* +// * Assumes MCLGETL returns cache-line-size aligned buffers. +// */ +// bf->bf_m = MCLGETL(NULL, M_DONTWAIT, ATHN_RXBUFSZ); +// if (bf->bf_m == NULL) { +// printf("%s: could not allocate Rx mbuf\n", +// sc->sc_dev.dv_xname); +// error = ENOBUFS; +// goto fail; +// } + +// error = bus_dmamap_load(sc->sc_dmat, bf->bf_map, +// mtod(bf->bf_m, void *), ATHN_RXBUFSZ, NULL, +// BUS_DMA_NOWAIT | BUS_DMA_READ); +// if (error != 0) { +// printf("%s: could not DMA map Rx buffer\n", +// sc->sc_dev.dv_xname); +// goto fail; +// } + +// bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, ATHN_RXBUFSZ, +// BUS_DMASYNC_PREREAD); + +// bf->bf_desc = ds; +// bf->bf_daddr = rxq->map->dm_segs[0].ds_addr + +// i * sizeof(struct ar_rx_desc); +// } +// return (0); +// fail: +// ar5008_rx_free(sc); +// return (error); +// } + +// void +// ar5008_rx_free(struct athn_softc *sc) +// { +// struct athn_rxq *rxq = &sc->rxq[0]; +// struct athn_rx_buf *bf; +// int i; + +// if (rxq->bf == NULL) +// return; +// for (i = 0; i < ATHN_NRXBUFS; i++) { +// bf = &rxq->bf[i]; + +// if (bf->bf_map != NULL) +// bus_dmamap_destroy(sc->sc_dmat, bf->bf_map); +// m_freem(bf->bf_m); +// } +// free(rxq->bf, M_DEVBUF, 0); + +// /* Free Rx descriptors. */ +// if (rxq->map != NULL) { +// if (rxq->descs != NULL) { +// bus_dmamap_unload(sc->sc_dmat, rxq->map); +// bus_dmamem_unmap(sc->sc_dmat, (caddr_t)rxq->descs, +// ATHN_NRXBUFS * sizeof(struct ar_rx_desc)); +// bus_dmamem_free(sc->sc_dmat, &rxq->seg, 1); +// } +// bus_dmamap_destroy(sc->sc_dmat, rxq->map); +// } +// } + +// void +// ar5008_rx_enable(struct athn_softc *sc) +// { +// struct athn_rxq *rxq = &sc->rxq[0]; +// struct athn_rx_buf *bf; +// struct ar_rx_desc *ds; +// int i; + +// /* Setup and link Rx descriptors. */ +// SIMPLEQ_INIT(&rxq->head); +// rxq->lastds = NULL; +// for (i = 0; i < ATHN_NRXBUFS; i++) { +// bf = &rxq->bf[i]; +// ds = bf->bf_desc; + +// memset(ds, 0, sizeof(*ds)); +// ds->ds_data = bf->bf_map->dm_segs[0].ds_addr; +// ds->ds_ctl1 = SM(AR_RXC1_BUF_LEN, ATHN_RXBUFSZ); + +// if (rxq->lastds != NULL) { +// ((struct ar_rx_desc *)rxq->lastds)->ds_link = +// bf->bf_daddr; +// } +// SIMPLEQ_INSERT_TAIL(&rxq->head, bf, bf_list); +// rxq->lastds = ds; +// } +// bus_dmamap_sync(sc->sc_dmat, rxq->map, 0, rxq->map->dm_mapsize, +// BUS_DMASYNC_PREREAD); + +// /* Enable Rx. */ +// AR_WRITE(sc, AR_RXDP, SIMPLEQ_FIRST(&rxq->head)->bf_daddr); +// AR_WRITE(sc, AR_CR, AR_CR_RXE); +// AR_WRITE_BARRIER(sc); +// } + +#if NBPFILTER > 0 +// void +// ar5008_rx_radiotap(struct athn_softc *sc, struct mbuf *m, +// struct ar_rx_desc *ds) +// { +// #define IEEE80211_RADIOTAP_F_SHORTGI 0x80 /* XXX from FBSD */ + +// struct athn_rx_radiotap_header *tap = &sc->sc_rxtap; +// struct ieee80211com *ic = &sc->sc_ic; +// uint64_t tsf; +// uint32_t tstamp; +// uint8_t rate; + +// /* Extend the 15-bit timestamp from Rx descriptor to 64-bit TSF. */ +// tstamp = ds->ds_status2; +// tsf = AR_READ(sc, AR_TSF_U32); +// tsf = tsf << 32 | AR_READ(sc, AR_TSF_L32); +// if ((tsf & 0x7fff) < tstamp) +// tsf -= 0x8000; +// tsf = (tsf & ~0x7fff) | tstamp; + +// tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; +// tap->wr_tsft = htole64(tsf); +// tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq); +// tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags); +// tap->wr_dbm_antsignal = MS(ds->ds_status4, AR_RXS4_RSSI_COMBINED); +// /* XXX noise. */ +// tap->wr_antenna = MS(ds->ds_status3, AR_RXS3_ANTENNA); +// tap->wr_rate = 0; /* In case it can't be found below. */ +// if (AR_SREV_5416_20_OR_LATER(sc)) +// rate = MS(ds->ds_status0, AR_RXS0_RATE); +// else +// rate = MS(ds->ds_status3, AR_RXS3_RATE); +// if (rate & 0x80) { /* HT. */ +// /* Bit 7 set means HT MCS instead of rate. */ +// tap->wr_rate = rate; +// if (!(ds->ds_status3 & AR_RXS3_GI)) +// tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI; + +// } else if (rate & 0x10) { /* CCK. */ +// if (rate & 0x04) +// tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; +// switch (rate & ~0x14) { +// case 0xb: tap->wr_rate = 2; break; +// case 0xa: tap->wr_rate = 4; break; +// case 0x9: tap->wr_rate = 11; break; +// case 0x8: tap->wr_rate = 22; break; +// } +// } else { /* OFDM. */ +// switch (rate) { +// case 0xb: tap->wr_rate = 12; break; +// case 0xf: tap->wr_rate = 18; break; +// case 0xa: tap->wr_rate = 24; break; +// case 0xe: tap->wr_rate = 36; break; +// case 0x9: tap->wr_rate = 48; break; +// case 0xd: tap->wr_rate = 72; break; +// case 0x8: tap->wr_rate = 96; break; +// case 0xc: tap->wr_rate = 108; break; +// } +// } +// bpf_mtap_hdr(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m, BPF_DIRECTION_IN); +// } +#endif + +// int +// ar5008_ccmp_decap(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni) +// { +// struct ieee80211com *ic = &sc->sc_ic; +// struct ieee80211_key *k; +// struct ieee80211_frame *wh; +// struct ieee80211_rx_ba *ba; +// uint64_t pn, *prsc; +// u_int8_t *ivp; +// uint8_t tid; +// int hdrlen, hasqos; +// uintptr_t entry; + +// wh = mtod(m, struct ieee80211_frame *); +// hdrlen = ieee80211_get_hdrlen(wh); +// ivp = mtod(m, u_int8_t *) + hdrlen; + +// /* find key for decryption */ +// k = ieee80211_get_rxkey(ic, m, ni); +// if (k == NULL || k->k_cipher != IEEE80211_CIPHER_CCMP) +// return 1; + +// /* Sanity checks to ensure this is really a key we installed. */ +// entry = (uintptr_t)k->k_priv; +// if (k->k_flags & IEEE80211_KEY_GROUP) { +// if (k->k_id >= IEEE80211_WEP_NKID || +// entry != k->k_id) +// return 1; +// } else { +// #ifndef IEEE80211_STA_ONLY +// if (ic->ic_opmode == IEEE80211_M_HOSTAP) { +// if (entry != IEEE80211_WEP_NKID + +// IEEE80211_AID(ni->ni_associd)) +// return 1; +// } else +// #endif +// if (entry != IEEE80211_WEP_NKID) +// return 1; +// } + +// /* Check that ExtIV bit is set. */ +// if (!(ivp[3] & IEEE80211_WEP_EXTIV)) +// return 1; + +// hasqos = ieee80211_has_qos(wh); +// tid = hasqos ? ieee80211_get_qos(wh) & IEEE80211_QOS_TID : 0; +// ba = hasqos ? &ni->ni_rx_ba[tid] : NULL; +// prsc = &k->k_rsc[tid]; + +// /* Extract the 48-bit PN from the CCMP header. */ +// pn = (uint64_t)ivp[0] | +// (uint64_t)ivp[1] << 8 | +// (uint64_t)ivp[4] << 16 | +// (uint64_t)ivp[5] << 24 | +// (uint64_t)ivp[6] << 32 | +// (uint64_t)ivp[7] << 40; +// if (pn <= *prsc) { +// ic->ic_stats.is_ccmp_replays++; +// return 1; +// } +// /* Last seen packet number is updated in ieee80211_inputm(). */ + +// /* Strip MIC. IV will be stripped by ieee80211_inputm(). */ +// m_adj(m, -IEEE80211_CCMP_MICLEN); +// return 0; +// } + +// static __inline int +// ar5008_rx_process(struct athn_softc *sc, struct mbuf_list *ml) +// { +// struct ieee80211com *ic = &sc->sc_ic; +// struct ifnet *ifp = &ic->ic_if; +// struct athn_rxq *rxq = &sc->rxq[0]; +// struct athn_rx_buf *bf, *nbf; +// struct ar_rx_desc *ds; +// struct ieee80211_frame *wh; +// struct ieee80211_rxinfo rxi; +// struct ieee80211_node *ni; +// struct mbuf *m, *m1; +// int error, len, michael_mic_failure = 0; + +// bf = SIMPLEQ_FIRST(&rxq->head); +// if (__predict_false(bf == NULL)) { /* Should not happen. */ +// printf("%s: Rx queue is empty!\n", sc->sc_dev.dv_xname); +// return (ENOENT); +// } +// ds = bf->bf_desc; + +// if (!(ds->ds_status8 & AR_RXS8_DONE)) { +// /* +// * On some parts, the status words can get corrupted +// * (including the "done" bit), so we check the next +// * descriptor "done" bit. If it is set, it is a good +// * indication that the status words are corrupted, so +// * we skip this descriptor and drop the frame. +// */ +// nbf = SIMPLEQ_NEXT(bf, bf_list); +// if (nbf != NULL && +// (((struct ar_rx_desc *)nbf->bf_desc)->ds_status8 & +// AR_RXS8_DONE)) { +// DPRINTF(("corrupted descriptor status=0x%x\n", +// ds->ds_status8)); +// /* HW will not "move" RXDP in this case, so do it. */ +// AR_WRITE(sc, AR_RXDP, nbf->bf_daddr); +// AR_WRITE_BARRIER(sc); +// ifp->if_ierrors++; +// goto skip; +// } +// return (EBUSY); +// } + +// if (__predict_false(ds->ds_status1 & AR_RXS1_MORE)) { +// /* Drop frames that span multiple Rx descriptors. */ +// DPRINTF(("dropping split frame\n")); +// ifp->if_ierrors++; +// goto skip; +// } +// if (!(ds->ds_status8 & AR_RXS8_FRAME_OK)) { +// if (ds->ds_status8 & AR_RXS8_CRC_ERR) +// DPRINTFN(6, ("CRC error\n")); +// else if (ds->ds_status8 & AR_RXS8_PHY_ERR) +// DPRINTFN(6, ("PHY error=0x%x\n", +// MS(ds->ds_status8, AR_RXS8_PHY_ERR_CODE))); +// else if (ds->ds_status8 & (AR_RXS8_DECRYPT_CRC_ERR | +// AR_RXS8_KEY_MISS | AR_RXS8_DECRYPT_BUSY_ERR)) { +// DPRINTFN(6, ("Decryption CRC error\n")); +// ic->ic_stats.is_ccmp_dec_errs++; +// } else if (ds->ds_status8 & AR_RXS8_MICHAEL_ERR) { +// DPRINTFN(2, ("Michael MIC failure\n")); +// michael_mic_failure = 1; +// } +// if (!michael_mic_failure) { +// ifp->if_ierrors++; +// goto skip; +// } +// } else { +// if (ds->ds_status8 & (AR_RXS8_CRC_ERR | AR_RXS8_PHY_ERR | +// AR_RXS8_DECRYPT_CRC_ERR | AR_RXS8_MICHAEL_ERR)) { +// ifp->if_ierrors++; +// goto skip; +// } +// } + +// len = MS(ds->ds_status1, AR_RXS1_DATA_LEN); +// if (__predict_false(len < IEEE80211_MIN_LEN || len > ATHN_RXBUFSZ)) { +// DPRINTF(("corrupted descriptor length=%d\n", len)); +// ifp->if_ierrors++; +// goto skip; +// } + +// /* Allocate a new Rx buffer. */ +// m1 = MCLGETL(NULL, M_DONTWAIT, ATHN_RXBUFSZ); +// if (__predict_false(m1 == NULL)) { +// ic->ic_stats.is_rx_nombuf++; +// ifp->if_ierrors++; +// goto skip; +// } + +// /* Sync and unmap the old Rx buffer. */ +// bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, ATHN_RXBUFSZ, +// BUS_DMASYNC_POSTREAD); +// bus_dmamap_unload(sc->sc_dmat, bf->bf_map); + +// /* Map the new Rx buffer. */ +// error = bus_dmamap_load(sc->sc_dmat, bf->bf_map, mtod(m1, void *), +// ATHN_RXBUFSZ, NULL, BUS_DMA_NOWAIT | BUS_DMA_READ); +// if (__predict_false(error != 0)) { +// m_freem(m1); + +// /* Remap the old Rx buffer or panic. */ +// error = bus_dmamap_load(sc->sc_dmat, bf->bf_map, +// mtod(bf->bf_m, void *), ATHN_RXBUFSZ, NULL, +// BUS_DMA_NOWAIT | BUS_DMA_READ); +// KASSERT(error != 0, "Panic in ar5008_rx_process"); +// ifp->if_ierrors++; +// goto skip; +// } + +// bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, ATHN_RXBUFSZ, +// BUS_DMASYNC_PREREAD); + +// /* Write physical address of new Rx buffer. */ +// ds->ds_data = bf->bf_map->dm_segs[0].ds_addr; + +// m = bf->bf_m; +// bf->bf_m = m1; + +// /* Finalize mbuf. */ +// m->m_pkthdr.len = m->m_len = len; + +// wh = mtod(m, struct ieee80211_frame *); + +// if (michael_mic_failure) { +// /* +// * Check that it is not a control frame +// * (invalid MIC failures on valid ctl frames). +// * Validate the transmitter's address to avoid passing +// * corrupt frames with bogus addresses to net80211. +// */ +// if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL)) { +// switch (ic->ic_opmode) { +// #ifndef IEEE80211_STA_ONLY +// case IEEE80211_M_HOSTAP: +// if (ieee80211_find_node(ic, wh->i_addr2)) +// michael_mic_failure = 0; +// break; +// #endif +// case IEEE80211_M_STA: +// if (IEEE80211_ADDR_EQ(wh->i_addr2, +// ic->ic_bss->ni_macaddr)) +// michael_mic_failure = 0; +// break; +// case IEEE80211_M_MONITOR: +// michael_mic_failure = 0; +// break; +// default: +// break; +// } +// } + +// if (michael_mic_failure) { +// /* Report Michael MIC failures to net80211. */ +// if ((ic->ic_rsnciphers & IEEE80211_CIPHER_TKIP) || +// ic->ic_rsngroupcipher == IEEE80211_CIPHER_TKIP) { +// ic->ic_stats.is_rx_locmicfail++; +// ieee80211_michael_mic_failure(ic, 0); +// } +// ifp->if_ierrors++; +// m_freem(m); +// goto skip; +// } +// } + +// /* Grab a reference to the source node. */ +// ni = ieee80211_find_rxnode(ic, wh); + +// /* Remove any HW padding after the 802.11 header. */ +// if (!(wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL)) { +// u_int hdrlen = ieee80211_get_hdrlen(wh); +// if (hdrlen & 3) { +// memmove((caddr_t)wh + 2, wh, hdrlen); +// m_adj(m, 2); +// } +// wh = mtod(m, struct ieee80211_frame *); +// } +// #if NBPFILTER > 0 +// if (__predict_false(sc->sc_drvbpf != NULL)) +// ar5008_rx_radiotap(sc, m, ds); +// #endif +// /* Trim 802.11 FCS after radiotap. */ +// m_adj(m, -IEEE80211_CRC_LEN); + +// /* Send the frame to the 802.11 layer. */ +// memset(&rxi, 0, sizeof(rxi)); +// rxi.rxi_rssi = MS(ds->ds_status4, AR_RXS4_RSSI_COMBINED); +// rxi.rxi_rssi += AR_DEFAULT_NOISE_FLOOR; +// rxi.rxi_tstamp = ds->ds_status2; +// if (!(wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL) && +// (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) && +// (ic->ic_flags & IEEE80211_F_RSNON) && +// (ni->ni_flags & IEEE80211_NODE_RXPROT) && +// ((!IEEE80211_IS_MULTICAST(wh->i_addr1) && +// ni->ni_rsncipher == IEEE80211_CIPHER_CCMP) || +// (IEEE80211_IS_MULTICAST(wh->i_addr1) && +// ni->ni_rsngroupcipher == IEEE80211_CIPHER_CCMP))) { +// if (ar5008_ccmp_decap(sc, m, ni) != 0) { +// ifp->if_ierrors++; +// ieee80211_release_node(ic, ni); +// m_freem(m); +// goto skip; +// } +// rxi.rxi_flags |= IEEE80211_RXI_HWDEC; +// } +// ieee80211_inputm(ifp, m, ni, &rxi, ml); + +// /* Node is no longer needed. */ +// ieee80211_release_node(ic, ni); + +// skip: +// /* Unlink this descriptor from head. */ +// SIMPLEQ_REMOVE_HEAD(&rxq->head, bf_list); +// memset(&ds->ds_status0, 0, 36); /* XXX Really needed? */ +// ds->ds_status8 &= ~AR_RXS8_DONE; +// ds->ds_link = 0; + +// /* Re-use this descriptor and link it to tail. */ +// if (__predict_true(!SIMPLEQ_EMPTY(&rxq->head))) +// ((struct ar_rx_desc *)rxq->lastds)->ds_link = bf->bf_daddr; +// else +// AR_WRITE(sc, AR_RXDP, bf->bf_daddr); +// SIMPLEQ_INSERT_TAIL(&rxq->head, bf, bf_list); +// rxq->lastds = ds; + +// /* Re-enable Rx. */ +// AR_WRITE(sc, AR_CR, AR_CR_RXE); +// AR_WRITE_BARRIER(sc); +// return (0); +// } + +// void +// ar5008_rx_intr(struct athn_softc *sc) +// { +// struct mbuf_list ml = MBUF_LIST_INITIALIZER(); +// struct ieee80211com *ic = &sc->sc_ic; +// struct ifnet *ifp = &ic->ic_if; + +// while (ar5008_rx_process(sc, &ml) == 0); + +// if_input(ifp, &ml); +// } + +// int +// ar5008_tx_process(struct athn_softc *sc, int qid) +// { +// struct ieee80211com *ic = &sc->sc_ic; +// struct ifnet *ifp = &ic->ic_if; +// struct athn_txq *txq = &sc->txq[qid]; +// struct athn_node *an; +// struct ieee80211_node *ni; +// struct athn_tx_buf *bf; +// struct ar_tx_desc *ds; +// uint8_t failcnt; +// int txfail = 0, rtscts; + +// bf = SIMPLEQ_FIRST(&txq->head); +// if (bf == NULL) +// return (ENOENT); +// /* Get descriptor of last DMA segment. */ +// ds = &((struct ar_tx_desc *)bf->bf_descs)[bf->bf_map->dm_nsegs - 1]; + +// if (!(ds->ds_status9 & AR_TXS9_DONE)) +// return (EBUSY); + +// SIMPLEQ_REMOVE_HEAD(&txq->head, bf_list); + +// sc->sc_tx_timer = 0; + +// /* These status bits are valid if “FRM_XMIT_OK” is clear. */ +// if ((ds->ds_status1 & AR_TXS1_FRM_XMIT_OK) == 0) { +// txfail = (ds->ds_status1 & AR_TXS1_EXCESSIVE_RETRIES); +// if (txfail) +// ifp->if_oerrors++; +// if (ds->ds_status1 & AR_TXS1_UNDERRUN) +// athn_inc_tx_trigger_level(sc); +// } + +// an = (struct athn_node *)bf->bf_ni; +// ni = (struct ieee80211_node *)bf->bf_ni; + +// /* +// * NB: the data fail count contains the number of un-acked tries +// * for the final series used. We must add the number of tries for +// * each series that was fully processed to punish transmit rates in +// * the earlier series which did not perform well. +// */ +// failcnt = MS(ds->ds_status1, AR_TXS1_DATA_FAIL_CNT); +// /* Assume two tries per series, as per AR_TXC2_XMIT_DATA_TRIESx. */ +// failcnt += MS(ds->ds_status9, AR_TXS9_FINAL_IDX) * 2; + +// rtscts = (ds->ds_ctl0 & (AR_TXC0_RTS_ENABLE | AR_TXC0_CTS_ENABLE)); + +// /* Update rate control statistics. */ +// if ((ni->ni_flags & IEEE80211_NODE_HT) && ic->ic_fixed_mcs == -1) { +// const struct ieee80211_ht_rateset *rs = +// ieee80211_ra_get_ht_rateset(bf->bf_txmcs, 0 /* chan40 */, +// ieee80211_node_supports_ht_sgi20(ni)); +// unsigned int retries = 0, i; +// int mcs = bf->bf_txmcs; + +// /* With RTS/CTS each Tx series used the same MCS. */ +// if (rtscts) { +// retries = failcnt; +// } else { +// for (i = 0; i < failcnt; i++) { +// if (mcs > rs->min_mcs) { +// ieee80211_ra_add_stats_ht(&an->rn, +// ic, ni, mcs, 1, 1); +// if (i % 2) /* two tries per series */ +// mcs--; +// } else +// retries++; +// } +// } + +// if (txfail && retries == 0) { +// ieee80211_ra_add_stats_ht(&an->rn, ic, ni, +// mcs, 1, 1); +// } else { +// ieee80211_ra_add_stats_ht(&an->rn, ic, ni, +// mcs, retries + 1, retries); +// } +// if (ic->ic_state == IEEE80211_S_RUN) { +// #ifndef IEEE80211_STA_ONLY +// if (ic->ic_opmode != IEEE80211_M_HOSTAP || +// ni->ni_state == IEEE80211_STA_ASSOC) +// #endif +// ieee80211_ra_choose(&an->rn, ic, ni); +// } +// } else if (ic->ic_fixed_rate == -1) { +// an->amn.amn_txcnt++; +// if (failcnt > 0) +// an->amn.amn_retrycnt++; +// } +// DPRINTFN(5, ("Tx done qid=%d status1=%d fail count=%d\n", +// qid, ds->ds_status1, failcnt)); + +// bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, bf->bf_map->dm_mapsize, +// BUS_DMASYNC_POSTWRITE); +// bus_dmamap_unload(sc->sc_dmat, bf->bf_map); + +// m_freem(bf->bf_m); +// bf->bf_m = NULL; +// ieee80211_release_node(ic, bf->bf_ni); +// bf->bf_ni = NULL; + +// /* Link Tx buffer back to global free list. */ +// SIMPLEQ_INSERT_TAIL(&sc->txbufs, bf, bf_list); +// return (0); +// } + +// void +// ar5008_tx_intr(struct athn_softc *sc) +// { +// struct ieee80211com *ic = &sc->sc_ic; +// struct ifnet *ifp = &ic->ic_if; +// uint16_t mask = 0; +// uint32_t reg; +// int qid; + +// reg = AR_READ(sc, AR_ISR_S0_S); +// mask |= MS(reg, AR_ISR_S0_QCU_TXOK); +// mask |= MS(reg, AR_ISR_S0_QCU_TXDESC); + +// reg = AR_READ(sc, AR_ISR_S1_S); +// mask |= MS(reg, AR_ISR_S1_QCU_TXERR); +// mask |= MS(reg, AR_ISR_S1_QCU_TXEOL); + +// DPRINTFN(4, ("Tx interrupt mask=0x%x\n", mask)); +// for (qid = 0; mask != 0; mask >>= 1, qid++) { +// if (mask & 1) +// while (ar5008_tx_process(sc, qid) == 0); +// } +// if (!SIMPLEQ_EMPTY(&sc->txbufs)) { +// ifq_clr_oactive(&ifp->if_snd); +// ifp->if_start(ifp); +// } +// } + +#ifndef IEEE80211_STA_ONLY +/* + * Process Software Beacon Alert interrupts. + */ +// int +// ar5008_swba_intr(struct athn_softc *sc) +// { +// struct ieee80211com *ic = &sc->sc_ic; +// struct ifnet *ifp = &ic->ic_if; +// struct ieee80211_node *ni = ic->ic_bss; +// struct athn_tx_buf *bf = sc->bcnbuf; +// struct ieee80211_frame *wh; +// struct ar_tx_desc *ds; +// struct mbuf *m; +// uint8_t ridx, hwrate; +// int error, totlen; + +// if (ic->ic_tim_mcast_pending && +// mq_empty(&ni->ni_savedq) && +// SIMPLEQ_EMPTY(&sc->txq[ATHN_QID_CAB].head)) +// ic->ic_tim_mcast_pending = 0; + +// if (ic->ic_dtim_count == 0) +// ic->ic_dtim_count = ic->ic_dtim_period - 1; +// else +// ic->ic_dtim_count--; + +// /* Make sure previous beacon has been sent. */ +// if (athn_tx_pending(sc, ATHN_QID_BEACON)) { +// DPRINTF(("beacon stuck\n")); +// return (EBUSY); +// } +// /* Get new beacon. */ +// m = ieee80211_beacon_alloc(ic, ic->ic_bss); +// if (__predict_false(m == NULL)) +// return (ENOBUFS); +// /* Assign sequence number. */ +// wh = mtod(m, struct ieee80211_frame *); +// *(uint16_t *)&wh->i_seq[0] = +// htole16(ic->ic_bss->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT); +// ic->ic_bss->ni_txseq++; + +// /* Unmap and free old beacon if any. */ +// if (__predict_true(bf->bf_m != NULL)) { +// bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, +// bf->bf_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); +// bus_dmamap_unload(sc->sc_dmat, bf->bf_map); +// m_freem(bf->bf_m); +// bf->bf_m = NULL; +// } +// /* DMA map new beacon. */ +// error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_map, m, +// BUS_DMA_NOWAIT | BUS_DMA_WRITE); +// if (__predict_false(error != 0)) { +// m_freem(m); +// return (error); +// } +// bf->bf_m = m; + +// /* Setup Tx descriptor (simplified ar5008_tx()). */ +// ds = bf->bf_descs; +// memset(ds, 0, sizeof(*ds)); + +// totlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; +// ds->ds_ctl0 = SM(AR_TXC0_FRAME_LEN, totlen); +// ds->ds_ctl0 |= SM(AR_TXC0_XMIT_POWER, AR_MAX_RATE_POWER); +// ds->ds_ctl1 = SM(AR_TXC1_FRAME_TYPE, AR_FRAME_TYPE_BEACON); +// ds->ds_ctl1 |= AR_TXC1_NO_ACK; +// ds->ds_ctl6 = SM(AR_TXC6_ENCR_TYPE, AR_ENCR_TYPE_CLEAR); + +// /* Write number of tries. */ +// ds->ds_ctl2 = SM(AR_TXC2_XMIT_DATA_TRIES0, 1); + +// /* Write Tx rate. */ +// ridx = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? +// ATHN_RIDX_OFDM6 : ATHN_RIDX_CCK1; +// hwrate = athn_rates[ridx].hwrate; +// ds->ds_ctl3 = SM(AR_TXC3_XMIT_RATE0, hwrate); + +// /* Write Tx chains. */ +// ds->ds_ctl7 = SM(AR_TXC7_CHAIN_SEL0, sc->txchainmask); + +// ds->ds_data = bf->bf_map->dm_segs[0].ds_addr; +// /* Segment length must be a multiple of 4. */ +// ds->ds_ctl1 |= SM(AR_TXC1_BUF_LEN, +// (bf->bf_map->dm_segs[0].ds_len + 3) & ~3); + +// bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, bf->bf_map->dm_mapsize, +// BUS_DMASYNC_PREWRITE); + +// /* Stop Tx DMA before putting the new beacon on the queue. */ +// athn_stop_tx_dma(sc, ATHN_QID_BEACON); + +// AR_WRITE(sc, AR_QTXDP(ATHN_QID_BEACON), bf->bf_daddr); + +// for(;;) { +// if (SIMPLEQ_EMPTY(&sc->txbufs)) +// break; + +// m = mq_dequeue(&ni->ni_savedq); +// if (m == NULL) +// break; +// if (!mq_empty(&ni->ni_savedq)) { +// /* more queued frames, set the more data bit */ +// wh = mtod(m, struct ieee80211_frame *); +// wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; +// } + +// if (sc->ops.tx(sc, m, ni, ATHN_TXFLAG_CAB) != 0) { +// ieee80211_release_node(ic, ni); +// ifp->if_oerrors++; +// break; +// } +// } + +// /* Kick Tx. */ +// AR_WRITE(sc, AR_Q_TXE, 1 << ATHN_QID_BEACON); +// AR_WRITE_BARRIER(sc); +// return (0); +// } +#endif + +// int +// ar5008_intr(struct athn_softc *sc) +// { +// uint32_t intr, intr2, intr5, sync; + +// /* Get pending interrupts. */ +// intr = AR_READ(sc, AR_INTR_ASYNC_CAUSE); +// if (!(intr & AR_INTR_MAC_IRQ) || intr == AR_INTR_SPURIOUS) { +// intr = AR_READ(sc, AR_INTR_SYNC_CAUSE); +// if (intr == AR_INTR_SPURIOUS || (intr & sc->isync) == 0) +// return (0); /* Not for us. */ +// } + +// if ((AR_READ(sc, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) && +// (AR_READ(sc, AR_RTC_STATUS) & AR_RTC_STATUS_M) == AR_RTC_STATUS_ON) +// intr = AR_READ(sc, AR_ISR); +// else +// intr = 0; +// sync = AR_READ(sc, AR_INTR_SYNC_CAUSE) & sc->isync; +// if (intr == 0 && sync == 0) +// return (0); /* Not for us. */ + +// if (intr != 0) { +// if (intr & AR_ISR_BCNMISC) { +// intr2 = AR_READ(sc, AR_ISR_S2); +// if (intr2 & AR_ISR_S2_TIM) +// /* TBD */; +// if (intr2 & AR_ISR_S2_TSFOOR) +// /* TBD */; +// } +// intr = AR_READ(sc, AR_ISR_RAC); +// if (intr == AR_INTR_SPURIOUS) +// return (1); + +// #ifndef IEEE80211_STA_ONLY +// if (intr & AR_ISR_SWBA) +// ar5008_swba_intr(sc); +// #endif +// if (intr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) +// ar5008_rx_intr(sc); +// if (intr & (AR_ISR_RXOK | AR_ISR_RXERR | AR_ISR_RXORN)) +// ar5008_rx_intr(sc); + +// if (intr & (AR_ISR_TXOK | AR_ISR_TXDESC | +// AR_ISR_TXERR | AR_ISR_TXEOL)) +// ar5008_tx_intr(sc); + +// intr5 = AR_READ(sc, AR_ISR_S5_S); +// if (intr & AR_ISR_GENTMR) { +// if (intr5 & AR_ISR_GENTMR) { +// DPRINTF(("GENTMR trigger=%d thresh=%d\n", +// MS(intr5, AR_ISR_S5_GENTIMER_TRIG), +// MS(intr5, AR_ISR_S5_GENTIMER_THRESH))); +// } +// } + +// if (intr5 & AR_ISR_S5_TIM_TIMER) +// /* TBD */; +// } +// if (sync != 0) { +// if (sync & (AR_INTR_SYNC_HOST1_FATAL | +// AR_INTR_SYNC_HOST1_PERR)) +// /* TBD */; + +// if (sync & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { +// AR_WRITE(sc, AR_RC, AR_RC_HOSTIF); +// AR_WRITE(sc, AR_RC, 0); +// } + +// if ((sc->flags & ATHN_FLAG_RFSILENT) && +// (sync & AR_INTR_SYNC_GPIO_PIN(sc->rfsilent_pin))) { +// struct ifnet *ifp = &sc->sc_ic.ic_if; + +// printf("%s: radio switch turned off\n", +// sc->sc_dev.dv_xname); +// /* Turn the interface down. */ +// athn_stop(ifp, 1); +// return (1); +// } + +// AR_WRITE(sc, AR_INTR_SYNC_CAUSE, sync); +// (void)AR_READ(sc, AR_INTR_SYNC_CAUSE); +// } +// return (1); +// } + +// int +// ar5008_ccmp_encap(struct mbuf *m, u_int hdrlen, struct ieee80211_key *k) +// { +// struct mbuf *n; +// uint8_t *ivp; +// int off; + +// /* Insert IV for CCMP hardware encryption. */ +// n = m_makespace(m, hdrlen, IEEE80211_CCMP_HDRLEN, &off); +// if (n == NULL) { +// m_freem(m); +// return (ENOBUFS); +// } +// ivp = mtod(n, uint8_t *) + off; +// k->k_tsc++; +// ivp[0] = k->k_tsc; +// ivp[1] = k->k_tsc >> 8; +// ivp[2] = 0; +// ivp[3] = k->k_id << 6 | IEEE80211_WEP_EXTIV; +// ivp[4] = k->k_tsc >> 16; +// ivp[5] = k->k_tsc >> 24; +// ivp[6] = k->k_tsc >> 32; +// ivp[7] = k->k_tsc >> 40; + +// return 0; +// } + +// int +// ar5008_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, +// int txflags) +// { +// struct ieee80211com *ic = &sc->sc_ic; +// struct ieee80211_key *k = NULL; +// struct ieee80211_frame *wh; +// struct athn_series series[4]; +// struct ar_tx_desc *ds, *lastds; +// struct athn_txq *txq; +// struct athn_tx_buf *bf; +// struct athn_node *an = (void *)ni; +// uintptr_t entry; +// uint16_t qos; +// uint8_t txpower, type, encrtype, tid, ridx[4]; +// int i, error, totlen, hasqos, qid; + +// /* Grab a Tx buffer from our global free list. */ +// bf = SIMPLEQ_FIRST(&sc->txbufs); +// KASSERT(bf != NULL, "Panic in ar5008tx"); + +// /* Map 802.11 frame type to hardware frame type. */ +// wh = mtod(m, struct ieee80211_frame *); +// if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == +// IEEE80211_FC0_TYPE_MGT) { +// /* NB: Beacons do not use ar5008_tx(). */ +// if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == +// IEEE80211_FC0_SUBTYPE_PROBE_RESP) +// type = AR_FRAME_TYPE_PROBE_RESP; +// else if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == +// IEEE80211_FC0_SUBTYPE_ATIM) +// type = AR_FRAME_TYPE_ATIM; +// else +// type = AR_FRAME_TYPE_NORMAL; +// } else if ((wh->i_fc[0] & +// (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == +// (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL)) { +// type = AR_FRAME_TYPE_PSPOLL; +// } else +// type = AR_FRAME_TYPE_NORMAL; + +// if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { +// k = ieee80211_get_txkey(ic, wh, ni); +// if (k->k_cipher == IEEE80211_CIPHER_CCMP) { +// u_int hdrlen = ieee80211_get_hdrlen(wh); +// if (ar5008_ccmp_encap(m, hdrlen, k) != 0) +// return (ENOBUFS); +// } else { +// if ((m = ieee80211_encrypt(ic, m, k)) == NULL) +// return (ENOBUFS); +// k = NULL; /* skip hardware crypto further below */ +// } +// wh = mtod(m, struct ieee80211_frame *); +// } + +// /* XXX 2-byte padding for QoS and 4-addr headers. */ + +// /* Select the HW Tx queue to use for this frame. */ +// if ((hasqos = ieee80211_has_qos(wh))) { +// qos = ieee80211_get_qos(wh); +// tid = qos & IEEE80211_QOS_TID; +// qid = athn_ac2qid[ieee80211_up_to_ac(ic, tid)]; +// } else if (type == AR_FRAME_TYPE_PSPOLL) { +// qid = ATHN_QID_PSPOLL; +// } else if (txflags & ATHN_TXFLAG_CAB) { +// qid = ATHN_QID_CAB; +// } else +// qid = ATHN_QID_AC_BE; +// txq = &sc->txq[qid]; + +// /* Select the transmit rates to use for this frame. */ +// if (IEEE80211_IS_MULTICAST(wh->i_addr1) || +// (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != +// IEEE80211_FC0_TYPE_DATA) { +// /* Use lowest rate for all tries. */ +// ridx[0] = ridx[1] = ridx[2] = ridx[3] = +// (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? +// ATHN_RIDX_OFDM6 : ATHN_RIDX_CCK1); +// } else if ((ni->ni_flags & IEEE80211_NODE_HT) && +// ic->ic_fixed_mcs != -1) { +// /* Use same fixed rate for all tries. */ +// ridx[0] = ridx[1] = ridx[2] = ridx[3] = +// ATHN_RIDX_MCS0 + ic->ic_fixed_mcs; +// } else if (ic->ic_fixed_rate != -1) { +// /* Use same fixed rate for all tries. */ +// ridx[0] = ridx[1] = ridx[2] = ridx[3] = +// sc->fixed_ridx; +// } else { +// /* Use fallback table of the node. */ +// int txrate; + +// if (ni->ni_flags & IEEE80211_NODE_HT) +// txrate = ATHN_NUM_LEGACY_RATES + ni->ni_txmcs; +// else +// txrate = ni->ni_txrate; +// for (i = 0; i < 4; i++) { +// ridx[i] = an->ridx[txrate]; +// txrate = an->fallback[txrate]; +// } +// } + +// #if NBPFILTER > 0 +// if (__predict_false(sc->sc_drvbpf != NULL)) { +// struct athn_tx_radiotap_header *tap = &sc->sc_txtap; + +// tap->wt_flags = 0; +// /* Use initial transmit rate. */ +// if (athn_rates[ridx[0]].hwrate & 0x80) /* MCS */ +// tap->wt_rate = athn_rates[ridx[0]].hwrate; +// else +// tap->wt_rate = athn_rates[ridx[0]].rate; +// tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq); +// tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags); +// if (athn_rates[ridx[0]].phy == IEEE80211_T_DS && +// ridx[0] != ATHN_RIDX_CCK1 && +// (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) +// tap->wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; +// bpf_mtap_hdr(sc->sc_drvbpf, tap, sc->sc_txtap_len, m, +// BPF_DIRECTION_OUT); +// } +// #endif + +// /* DMA map mbuf. */ +// error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_map, m, +// BUS_DMA_NOWAIT | BUS_DMA_WRITE); +// if (__predict_false(error != 0)) { +// if (error != EFBIG) { +// printf("%s: can't map mbuf (error %d)\n", +// sc->sc_dev.dv_xname, error); +// m_freem(m); +// return (error); +// } +// /* +// * DMA mapping requires too many DMA segments; linearize +// * mbuf in kernel virtual address space and retry. +// */ +// if (m_defrag(m, M_DONTWAIT) != 0) { +// m_freem(m); +// return (ENOBUFS); +// } + +// error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_map, m, +// BUS_DMA_NOWAIT | BUS_DMA_WRITE); +// if (error != 0) { +// printf("%s: can't map mbuf (error %d)\n", +// sc->sc_dev.dv_xname, error); +// m_freem(m); +// return (error); +// } +// } +// bf->bf_m = m; +// bf->bf_ni = ni; +// bf->bf_txmcs = ni->ni_txmcs; +// bf->bf_txflags = txflags; + +// wh = mtod(m, struct ieee80211_frame *); + +// totlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; + +// /* Clear all Tx descriptors that we will use. */ +// memset(bf->bf_descs, 0, bf->bf_map->dm_nsegs * sizeof(*ds)); + +// /* Setup first Tx descriptor. */ +// ds = bf->bf_descs; + +// ds->ds_ctl0 = AR_TXC0_INTR_REQ | AR_TXC0_CLR_DEST_MASK; +// txpower = AR_MAX_RATE_POWER; /* Get from per-rate registers. */ +// ds->ds_ctl0 |= SM(AR_TXC0_XMIT_POWER, txpower); + +// ds->ds_ctl1 = SM(AR_TXC1_FRAME_TYPE, type); + +// if (IEEE80211_IS_MULTICAST(wh->i_addr1) || +// (hasqos && (qos & IEEE80211_QOS_ACK_POLICY_MASK) == +// IEEE80211_QOS_ACK_POLICY_NOACK)) +// ds->ds_ctl1 |= AR_TXC1_NO_ACK; + +// if (k != NULL) { +// /* Map 802.11 cipher to hardware encryption type. */ +// if (k->k_cipher == IEEE80211_CIPHER_CCMP) { +// encrtype = AR_ENCR_TYPE_AES; +// totlen += IEEE80211_CCMP_MICLEN; +// } else +// panic("unsupported cipher"); +// /* +// * NB: The key cache entry index is stored in the key +// * private field when the key is installed. +// */ +// entry = (uintptr_t)k->k_priv; +// ds->ds_ctl1 |= SM(AR_TXC1_DEST_IDX, entry); +// ds->ds_ctl0 |= AR_TXC0_DEST_IDX_VALID; +// } else +// encrtype = AR_ENCR_TYPE_CLEAR; +// ds->ds_ctl6 = SM(AR_TXC6_ENCR_TYPE, encrtype); + +// /* Check if frame must be protected using RTS/CTS or CTS-to-self. */ +// if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && +// (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == +// IEEE80211_FC0_TYPE_DATA) { +// enum ieee80211_htprot htprot; + +// htprot = (ic->ic_bss->ni_htop1 & IEEE80211_HTOP1_PROT_MASK); + +// /* NB: Group frames are sent using CCK in 802.11b/g. */ +// if (totlen > ic->ic_rtsthreshold) { +// ds->ds_ctl0 |= AR_TXC0_RTS_ENABLE; +// } else if (((ic->ic_flags & IEEE80211_F_USEPROT) && +// athn_rates[ridx[0]].phy == IEEE80211_T_OFDM) || +// ((ni->ni_flags & IEEE80211_NODE_HT) && +// htprot != IEEE80211_HTPROT_NONE)) { +// if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) +// ds->ds_ctl0 |= AR_TXC0_RTS_ENABLE; +// else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) +// ds->ds_ctl0 |= AR_TXC0_CTS_ENABLE; +// } +// } +// /* +// * Disable multi-rate retries when protection is used. +// * The RTS/CTS frame's duration field is fixed and won't be +// * updated by hardware when the data rate changes. +// */ +// if (ds->ds_ctl0 & (AR_TXC0_RTS_ENABLE | AR_TXC0_CTS_ENABLE)) { +// ridx[1] = ridx[2] = ridx[3] = ridx[0]; +// } +// /* Setup multi-rate retries. */ +// for (i = 0; i < 4; i++) { +// series[i].hwrate = athn_rates[ridx[i]].hwrate; +// if (athn_rates[ridx[i]].phy == IEEE80211_T_DS && +// ridx[i] != ATHN_RIDX_CCK1 && +// (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) +// series[i].hwrate |= 0x04; +// /* Compute duration for each series. */ +// series[i].dur = athn_txtime(sc, totlen, ridx[i], ic->ic_flags); +// if (!(ds->ds_ctl1 & AR_TXC1_NO_ACK)) { +// /* Account for ACK duration. */ +// series[i].dur += athn_txtime(sc, IEEE80211_ACK_LEN, +// athn_rates[ridx[i]].rspridx, ic->ic_flags); +// } +// } + +// /* Write number of tries for each series. */ +// ds->ds_ctl2 = +// SM(AR_TXC2_XMIT_DATA_TRIES0, 2) | +// SM(AR_TXC2_XMIT_DATA_TRIES1, 2) | +// SM(AR_TXC2_XMIT_DATA_TRIES2, 2) | +// SM(AR_TXC2_XMIT_DATA_TRIES3, 4); + +// /* Tell HW to update duration field in 802.11 header. */ +// if (type != AR_FRAME_TYPE_PSPOLL) +// ds->ds_ctl2 |= AR_TXC2_DUR_UPDATE_ENA; + +// /* Write Tx rate for each series. */ +// ds->ds_ctl3 = +// SM(AR_TXC3_XMIT_RATE0, series[0].hwrate) | +// SM(AR_TXC3_XMIT_RATE1, series[1].hwrate) | +// SM(AR_TXC3_XMIT_RATE2, series[2].hwrate) | +// SM(AR_TXC3_XMIT_RATE3, series[3].hwrate); + +// /* Write duration for each series. */ +// ds->ds_ctl4 = +// SM(AR_TXC4_PACKET_DUR0, series[0].dur) | +// SM(AR_TXC4_PACKET_DUR1, series[1].dur); +// ds->ds_ctl5 = +// SM(AR_TXC5_PACKET_DUR2, series[2].dur) | +// SM(AR_TXC5_PACKET_DUR3, series[3].dur); + +// /* Use the same Tx chains for all tries. */ +// ds->ds_ctl7 = +// SM(AR_TXC7_CHAIN_SEL0, sc->txchainmask) | +// SM(AR_TXC7_CHAIN_SEL1, sc->txchainmask) | +// SM(AR_TXC7_CHAIN_SEL2, sc->txchainmask) | +// SM(AR_TXC7_CHAIN_SEL3, sc->txchainmask); +// #ifdef notyet +// /* Use the same short GI setting for all tries. */ +// if (ni->ni_htcaps & IEEE80211_HTCAP_SGI20) +// ds->ds_ctl7 |= AR_TXC7_GI0123; +// /* Use the same channel width for all tries. */ +// if (ic->ic_flags & IEEE80211_F_CBW40) +// ds->ds_ctl7 |= AR_TXC7_2040_0123; +// #endif + +// /* Set Tx power for series 1 - 3 */ +// ds->ds_ctl9 = SM(AR_TXC9_XMIT_POWER1, txpower); +// ds->ds_ctl10 = SM(AR_TXC10_XMIT_POWER2, txpower); +// ds->ds_ctl11 = SM(AR_TXC11_XMIT_POWER3, txpower); + +// if (ds->ds_ctl0 & (AR_TXC0_RTS_ENABLE | AR_TXC0_CTS_ENABLE)) { +// uint8_t protridx, hwrate; +// uint16_t dur = 0; + +// /* Use the same protection mode for all tries. */ +// if (ds->ds_ctl0 & AR_TXC0_RTS_ENABLE) { +// ds->ds_ctl4 |= AR_TXC4_RTSCTS_QUAL01; +// ds->ds_ctl5 |= AR_TXC5_RTSCTS_QUAL23; +// } +// /* Select protection rate (suboptimal but ok). */ +// protridx = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? +// ATHN_RIDX_OFDM6 : ATHN_RIDX_CCK2; +// if (ds->ds_ctl0 & AR_TXC0_RTS_ENABLE) { +// /* Account for CTS duration. */ +// dur += athn_txtime(sc, IEEE80211_ACK_LEN, +// athn_rates[protridx].rspridx, ic->ic_flags); +// } +// dur += athn_txtime(sc, totlen, ridx[0], ic->ic_flags); +// if (!(ds->ds_ctl1 & AR_TXC1_NO_ACK)) { +// /* Account for ACK duration. */ +// dur += athn_txtime(sc, IEEE80211_ACK_LEN, +// athn_rates[ridx[0]].rspridx, ic->ic_flags); +// } +// /* Write protection frame duration and rate. */ +// ds->ds_ctl2 |= SM(AR_TXC2_BURST_DUR, dur); +// hwrate = athn_rates[protridx].hwrate; +// if (protridx == ATHN_RIDX_CCK2 && +// (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) +// hwrate |= 0x04; +// ds->ds_ctl7 |= SM(AR_TXC7_RTSCTS_RATE, hwrate); +// } + +// /* Finalize first Tx descriptor and fill others (if any). */ +// ds->ds_ctl0 |= SM(AR_TXC0_FRAME_LEN, totlen); + +// for (i = 0; i < bf->bf_map->dm_nsegs; i++, ds++) { +// ds->ds_data = bf->bf_map->dm_segs[i].ds_addr; +// ds->ds_ctl1 |= SM(AR_TXC1_BUF_LEN, +// bf->bf_map->dm_segs[i].ds_len); + +// if (i != bf->bf_map->dm_nsegs - 1) +// ds->ds_ctl1 |= AR_TXC1_MORE; +// ds->ds_link = 0; + +// /* Chain Tx descriptor. */ +// if (i != 0) +// lastds->ds_link = bf->bf_daddr + i * sizeof(*ds); +// lastds = ds; +// } +// bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, bf->bf_map->dm_mapsize, +// BUS_DMASYNC_PREWRITE); + +// if (!SIMPLEQ_EMPTY(&txq->head)) +// ((struct ar_tx_desc *)txq->lastds)->ds_link = bf->bf_daddr; +// else +// AR_WRITE(sc, AR_QTXDP(qid), bf->bf_daddr); +// txq->lastds = lastds; +// SIMPLEQ_REMOVE_HEAD(&sc->txbufs, bf_list); +// SIMPLEQ_INSERT_TAIL(&txq->head, bf, bf_list); + +// ds = bf->bf_descs; +// DPRINTFN(6, ("Tx qid=%d nsegs=%d ctl0=0x%x ctl1=0x%x ctl3=0x%x\n", +// qid, bf->bf_map->dm_nsegs, ds->ds_ctl0, ds->ds_ctl1, ds->ds_ctl3)); + +// /* Kick Tx. */ +// AR_WRITE(sc, AR_Q_TXE, 1 << qid); +// AR_WRITE_BARRIER(sc); +// return (0); +// } + +void +ar5008_set_rf_mode(struct athn_softc *sc, struct ieee80211_channel *c) +{ + uint32_t reg; + + reg = IEEE80211_IS_CHAN_2GHZ(c) ? + AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; + if (!AR_SREV_9280_10_OR_LATER(sc)) { + reg |= IEEE80211_IS_CHAN_2GHZ(c) ? + AR_PHY_MODE_RF2GHZ : AR_PHY_MODE_RF5GHZ; + } else if (IEEE80211_IS_CHAN_5GHZ(c) && + (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK)) { + reg |= AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE; + } + AR_WRITE(sc, AR_PHY_MODE, reg); + AR_WRITE_BARRIER(sc); +} + +static __inline uint32_t +ar5008_synth_delay(struct athn_softc *sc) +{ + uint32_t delay; + + delay = MS(AR_READ(sc, AR_PHY_RX_DELAY), AR_PHY_RX_DELAY_DELAY); + if (sc->sc_ic.ic_curmode == IEEE80211_MODE_11B) + delay = (delay * 4) / 22; + else + delay = delay / 10; /* in 100ns steps */ + return (delay); +} + +int +ar5008_rf_bus_request(struct athn_softc *sc) +{ + int ntries; + + /* Request RF Bus grant. */ + AR_WRITE(sc, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN); + for (ntries = 0; ntries < 10000; ntries++) { + if (AR_READ(sc, AR_PHY_RFBUS_GRANT) & AR_PHY_RFBUS_GRANT_EN) + return (0); + DELAY(10); + } + DPRINTF(("could not kill baseband Rx")); + return (ETIMEDOUT); +} + +void +ar5008_rf_bus_release(struct athn_softc *sc) +{ + /* Wait for the synthesizer to settle. */ + DELAY(AR_BASE_PHY_ACTIVE_DELAY + ar5008_synth_delay(sc)); + + /* Release the RF Bus grant. */ + AR_WRITE(sc, AR_PHY_RFBUS_REQ, 0); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_set_phy(struct athn_softc *sc, struct ieee80211_channel *c, + struct ieee80211_channel *extc) +{ + uint32_t phy; + + if (AR_SREV_9285_10_OR_LATER(sc)) + phy = AR_READ(sc, AR_PHY_TURBO) & AR_PHY_FC_ENABLE_DAC_FIFO; + else + phy = 0; + phy |= AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 | + AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH; + if (extc != NULL) { + phy |= AR_PHY_FC_DYN2040_EN; + if (extc > c) /* XXX */ + phy |= AR_PHY_FC_DYN2040_PRI_CH; + } + AR_WRITE(sc, AR_PHY_TURBO, phy); + + AR_WRITE(sc, AR_2040_MODE, + (extc != NULL) ? AR_2040_JOINED_RX_CLEAR : 0); + + /* Set global transmit timeout. */ + AR_WRITE(sc, AR_GTXTO, SM(AR_GTXTO_TIMEOUT_LIMIT, 25)); + /* Set carrier sense timeout. */ + AR_WRITE(sc, AR_CST, SM(AR_CST_TIMEOUT_LIMIT, 15)); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_set_delta_slope(struct athn_softc *sc, struct ieee80211_channel *c, + struct ieee80211_channel *extc) +{ + uint32_t coeff, exp, man, reg; + + /* Set Delta Slope (exponent and mantissa). */ + coeff = (100 << 24) / c->ic_freq; + athn_get_delta_slope(coeff, &exp, &man); + DPRINTFN(5, ("delta slope coeff exp=%u man=%u\n", exp, man)); + + reg = AR_READ(sc, AR_PHY_TIMING3); + reg = RW(reg, AR_PHY_TIMING3_DSC_EXP, exp); + reg = RW(reg, AR_PHY_TIMING3_DSC_MAN, man); + AR_WRITE(sc, AR_PHY_TIMING3, reg); + + /* For Short GI, coeff is 9/10 that of normal coeff. */ + coeff = (9 * coeff) / 10; + athn_get_delta_slope(coeff, &exp, &man); + DPRINTFN(5, ("delta slope coeff exp=%u man=%u\n", exp, man)); + + reg = AR_READ(sc, AR_PHY_HALFGI); + reg = RW(reg, AR_PHY_HALFGI_DSC_EXP, exp); + reg = RW(reg, AR_PHY_HALFGI_DSC_MAN, man); + AR_WRITE(sc, AR_PHY_HALFGI, reg); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_enable_antenna_diversity(struct athn_softc *sc) +{ + AR_SETBITS(sc, AR_PHY_CCK_DETECT, + AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_init_baseband(struct athn_softc *sc) +{ + uint32_t synth_delay; + + synth_delay = ar5008_synth_delay(sc); + /* Activate the PHY (includes baseband activate and synthesizer on). */ + AR_WRITE(sc, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); + AR_WRITE_BARRIER(sc); + DELAY(AR_BASE_PHY_ACTIVE_DELAY + synth_delay); +} + +void +ar5008_disable_phy(struct athn_softc *sc) +{ + AR_WRITE(sc, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_init_chains(struct athn_softc *sc) +{ + if (sc->rxchainmask == 0x5 || sc->txchainmask == 0x5) + AR_SETBITS(sc, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN); + + /* Setup chain masks. */ + if (sc->mac_ver <= AR_SREV_VERSION_9160 && + (sc->rxchainmask == 0x3 || sc->rxchainmask == 0x5)) { + AR_WRITE(sc, AR_PHY_RX_CHAINMASK, 0x7); + AR_WRITE(sc, AR_PHY_CAL_CHAINMASK, 0x7); + } else { + AR_WRITE(sc, AR_PHY_RX_CHAINMASK, sc->rxchainmask); + AR_WRITE(sc, AR_PHY_CAL_CHAINMASK, sc->rxchainmask); + } + AR_WRITE(sc, AR_SELFGEN_MASK, sc->txchainmask); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_set_rxchains(struct athn_softc *sc) +{ + if (sc->rxchainmask == 0x3 || sc->rxchainmask == 0x5) { + AR_WRITE(sc, AR_PHY_RX_CHAINMASK, sc->rxchainmask); + AR_WRITE(sc, AR_PHY_CAL_CHAINMASK, sc->rxchainmask); + AR_WRITE_BARRIER(sc); + } +} + +void +ar5008_read_noisefloor(struct athn_softc *sc, int16_t *nf, int16_t *nf_ext) +{ +/* Sign-extends 9-bit value (assumes upper bits are zeroes). */ +#define SIGN_EXT(v) (((v) ^ 0x100) - 0x100) + uint32_t reg; + int i; + + for (i = 0; i < sc->nrxchains; i++) { + reg = AR_READ(sc, AR_PHY_CCA(i)); + if (AR_SREV_9280_10_OR_LATER(sc)) + nf[i] = MS(reg, AR9280_PHY_MINCCA_PWR); + else + nf[i] = MS(reg, AR_PHY_MINCCA_PWR); + nf[i] = SIGN_EXT(nf[i]); + + reg = AR_READ(sc, AR_PHY_EXT_CCA(i)); + if (AR_SREV_9280_10_OR_LATER(sc)) + nf_ext[i] = MS(reg, AR9280_PHY_EXT_MINCCA_PWR); + else + nf_ext[i] = MS(reg, AR_PHY_EXT_MINCCA_PWR); + nf_ext[i] = SIGN_EXT(nf_ext[i]); + } +#undef SIGN_EXT +} + +void +ar5008_write_noisefloor(struct athn_softc *sc, int16_t *nf, int16_t *nf_ext) +{ + uint32_t reg; + int i; + + for (i = 0; i < sc->nrxchains; i++) { + reg = AR_READ(sc, AR_PHY_CCA(i)); + reg = RW(reg, AR_PHY_MAXCCA_PWR, nf[i]); + AR_WRITE(sc, AR_PHY_CCA(i), reg); + + reg = AR_READ(sc, AR_PHY_EXT_CCA(i)); + reg = RW(reg, AR_PHY_EXT_MAXCCA_PWR, nf_ext[i]); + AR_WRITE(sc, AR_PHY_EXT_CCA(i), reg); + } + AR_WRITE_BARRIER(sc); +} + +int +ar5008_get_noisefloor(struct athn_softc *sc) +{ + int16_t nf[AR_MAX_CHAINS], nf_ext[AR_MAX_CHAINS]; + int i; + + if (AR_READ(sc, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { + /* Noisefloor calibration not finished. */ + return 0; + } + /* Noisefloor calibration is finished. */ + ar5008_read_noisefloor(sc, nf, nf_ext); + + /* Update noisefloor history. */ + for (i = 0; i < sc->nrxchains; i++) { + sc->nf_hist[sc->nf_hist_cur].nf[i] = nf[i]; + sc->nf_hist[sc->nf_hist_cur].nf_ext[i] = nf_ext[i]; + } + if (++sc->nf_hist_cur >= ATHN_NF_CAL_HIST_MAX) + sc->nf_hist_cur = 0; + return 1; +} + +void +ar5008_bb_load_noisefloor(struct athn_softc *sc) +{ + int16_t nf[AR_MAX_CHAINS], nf_ext[AR_MAX_CHAINS]; + int i, ntries; + + /* Write filtered noisefloor values. */ + for (i = 0; i < sc->nrxchains; i++) { + nf[i] = sc->nf_priv[i] * 2; + nf_ext[i] = sc->nf_ext_priv[i] * 2; + } + ar5008_write_noisefloor(sc, nf, nf_ext); + + /* Load filtered noisefloor values into baseband. */ + AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF); + AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF); + AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); + /* Wait for load to complete. */ + for (ntries = 0; ntries < 1000; ntries++) { + if (!(AR_READ(sc, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF)) + break; + DELAY(50); + } + if (ntries == 1000) { + DPRINTF(("failed to load noisefloor values\n")); + return; + } + + /* + * Restore noisefloor values to initial (max) values. These will + * be used as initial values during the next NF calibration. + */ + for (i = 0; i < AR_MAX_CHAINS; i++) + nf[i] = nf_ext[i] = AR_DEFAULT_NOISE_FLOOR; + ar5008_write_noisefloor(sc, nf, nf_ext); +} + +void +ar5008_apply_noisefloor(struct athn_softc *sc) +{ + uint32_t agc_nfcal; + + agc_nfcal = AR_READ(sc, AR_PHY_AGC_CONTROL) & + (AR_PHY_AGC_CONTROL_NF | AR_PHY_AGC_CONTROL_ENABLE_NF | + AR_PHY_AGC_CONTROL_NO_UPDATE_NF); + + if (agc_nfcal & AR_PHY_AGC_CONTROL_NF) { + /* Pause running NF calibration while values are updated. */ + AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); + AR_WRITE_BARRIER(sc); + } + + ar5008_bb_load_noisefloor(sc); + + if (agc_nfcal & AR_PHY_AGC_CONTROL_NF) { + /* Restart interrupted NF calibration. */ + AR_SETBITS(sc, AR_PHY_AGC_CONTROL, agc_nfcal); + AR_WRITE_BARRIER(sc); + } +} + +void +ar5008_do_noisefloor_calib(struct athn_softc *sc) +{ + AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF); + AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF); + AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_init_noisefloor_calib(struct athn_softc *sc) +{ + AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_do_calib(struct athn_softc *sc) +{ + uint32_t mode, reg; + int log; + + reg = AR_READ(sc, AR_PHY_TIMING_CTRL4_0); + log = AR_SREV_9280_10_OR_LATER(sc) ? 10 : 2; + reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX, log); + AR_WRITE(sc, AR_PHY_TIMING_CTRL4_0, reg); + + if (sc->cur_calib_mask & ATHN_CAL_ADC_GAIN) + mode = AR_PHY_CALMODE_ADC_GAIN; + else if (sc->cur_calib_mask & ATHN_CAL_ADC_DC) + mode = AR_PHY_CALMODE_ADC_DC_PER; + else /* ATHN_CAL_IQ */ + mode = AR_PHY_CALMODE_IQ; + AR_WRITE(sc, AR_PHY_CALMODE, mode); + + DPRINTF(("starting calibration mode=0x%x\n", mode)); + AR_SETBITS(sc, AR_PHY_TIMING_CTRL4_0, AR_PHY_TIMING_CTRL4_DO_CAL); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_next_calib(struct athn_softc *sc) +{ + /* Check if we have any calibration in progress. */ + if (sc->cur_calib_mask != 0) { + if (!(AR_READ(sc, AR_PHY_TIMING_CTRL4_0) & + AR_PHY_TIMING_CTRL4_DO_CAL)) { + /* Calibration completed for current sample. */ + if (sc->cur_calib_mask & ATHN_CAL_ADC_GAIN) + ar5008_calib_adc_gain(sc); + else if (sc->cur_calib_mask & ATHN_CAL_ADC_DC) + ar5008_calib_adc_dc_off(sc); + else /* ATHN_CAL_IQ */ + ar5008_calib_iq(sc); + } + } +} + +void +ar5008_calib_iq(struct athn_softc *sc) +{ + struct athn_iq_cal *cal; + uint32_t reg, i_coff_denom, q_coff_denom; + int32_t i_coff, q_coff; + int i, iq_corr_neg; + + for (i = 0; i < AR_MAX_CHAINS; i++) { + cal = &sc->calib.iq[i]; + + /* Accumulate IQ calibration measures (clear on read). */ + cal->pwr_meas_i += AR_READ(sc, AR_PHY_CAL_MEAS_0(i)); + cal->pwr_meas_q += AR_READ(sc, AR_PHY_CAL_MEAS_1(i)); + cal->iq_corr_meas += + (int32_t)AR_READ(sc, AR_PHY_CAL_MEAS_2(i)); + } + if (!AR_SREV_9280_10_OR_LATER(sc) && + ++sc->calib.nsamples < AR_CAL_SAMPLES) { + /* Not enough samples accumulated, continue. */ + ar5008_do_calib(sc); + return; + } + + for (i = 0; i < sc->nrxchains; i++) { + cal = &sc->calib.iq[i]; + + if (cal->pwr_meas_q == 0) + continue; + + if ((iq_corr_neg = cal->iq_corr_meas < 0)) + cal->iq_corr_meas = -cal->iq_corr_meas; + + i_coff_denom = + (cal->pwr_meas_i / 2 + cal->pwr_meas_q / 2) / 128; + q_coff_denom = cal->pwr_meas_q / 64; + + if (i_coff_denom == 0 || q_coff_denom == 0) + continue; /* Prevents division by zero. */ + + i_coff = cal->iq_corr_meas / i_coff_denom; + q_coff = (cal->pwr_meas_i / q_coff_denom) - 64; + + /* Negate i_coff if iq_corr_meas is positive. */ + if (!iq_corr_neg) + i_coff = 0x40 - (i_coff & 0x3f); + if (q_coff > 15) + q_coff = 15; + else if (q_coff <= -16) + q_coff = -16; /* XXX Linux has a bug here? */ + + DPRINTFN(2, ("IQ calibration for chain %d\n", i)); + reg = AR_READ(sc, AR_PHY_TIMING_CTRL4(i)); + reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, i_coff); + reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, q_coff); + AR_WRITE(sc, AR_PHY_TIMING_CTRL4(i), reg); + } + + /* Apply new settings. */ + AR_SETBITS(sc, AR_PHY_TIMING_CTRL4_0, + AR_PHY_TIMING_CTRL4_IQCORR_ENABLE); + AR_WRITE_BARRIER(sc); + + /* IQ calibration done. */ + sc->cur_calib_mask &= ~ATHN_CAL_IQ; + memset(&sc->calib, 0, sizeof(sc->calib)); +} + +void +ar5008_calib_adc_gain(struct athn_softc *sc) +{ + struct athn_adc_cal *cal; + uint32_t reg, gain_mismatch_i, gain_mismatch_q; + int i; + + for (i = 0; i < AR_MAX_CHAINS; i++) { + cal = &sc->calib.adc_gain[i]; + + /* Accumulate ADC gain measures (clear on read). */ + cal->pwr_meas_odd_i += AR_READ(sc, AR_PHY_CAL_MEAS_0(i)); + cal->pwr_meas_even_i += AR_READ(sc, AR_PHY_CAL_MEAS_1(i)); + cal->pwr_meas_odd_q += AR_READ(sc, AR_PHY_CAL_MEAS_2(i)); + cal->pwr_meas_even_q += AR_READ(sc, AR_PHY_CAL_MEAS_3(i)); + } + if (!AR_SREV_9280_10_OR_LATER(sc) && + ++sc->calib.nsamples < AR_CAL_SAMPLES) { + /* Not enough samples accumulated, continue. */ + ar5008_do_calib(sc); + return; + } + + for (i = 0; i < sc->nrxchains; i++) { + cal = &sc->calib.adc_gain[i]; + + if (cal->pwr_meas_odd_i == 0 || cal->pwr_meas_even_q == 0) + continue; /* Prevents division by zero. */ + + gain_mismatch_i = + (cal->pwr_meas_even_i * 32) / cal->pwr_meas_odd_i; + gain_mismatch_q = + (cal->pwr_meas_odd_q * 32) / cal->pwr_meas_even_q; + + DPRINTFN(2, ("ADC gain calibration for chain %d\n", i)); + reg = AR_READ(sc, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); + reg = RW(reg, AR_PHY_NEW_ADC_DC_GAIN_IGAIN, gain_mismatch_i); + reg = RW(reg, AR_PHY_NEW_ADC_DC_GAIN_QGAIN, gain_mismatch_q); + AR_WRITE(sc, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), reg); + } + + /* Apply new settings. */ + AR_SETBITS(sc, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), + AR_PHY_NEW_ADC_GAIN_CORR_ENABLE); + AR_WRITE_BARRIER(sc); + + /* ADC gain calibration done. */ + sc->cur_calib_mask &= ~ATHN_CAL_ADC_GAIN; + memset(&sc->calib, 0, sizeof(sc->calib)); +} + +void +ar5008_calib_adc_dc_off(struct athn_softc *sc) +{ + struct athn_adc_cal *cal; + int32_t dc_offset_mismatch_i, dc_offset_mismatch_q; + uint32_t reg; + int count, i; + + for (i = 0; i < AR_MAX_CHAINS; i++) { + cal = &sc->calib.adc_dc_offset[i]; + + /* Accumulate ADC DC offset measures (clear on read). */ + cal->pwr_meas_odd_i += AR_READ(sc, AR_PHY_CAL_MEAS_0(i)); + cal->pwr_meas_even_i += AR_READ(sc, AR_PHY_CAL_MEAS_1(i)); + cal->pwr_meas_odd_q += AR_READ(sc, AR_PHY_CAL_MEAS_2(i)); + cal->pwr_meas_even_q += AR_READ(sc, AR_PHY_CAL_MEAS_3(i)); + } + if (!AR_SREV_9280_10_OR_LATER(sc) && + ++sc->calib.nsamples < AR_CAL_SAMPLES) { + /* Not enough samples accumulated, continue. */ + ar5008_do_calib(sc); + return; + } + + if (AR_SREV_9280_10_OR_LATER(sc)) + count = (1 << (10 + 5)); + else + count = (1 << ( 2 + 5)) * AR_CAL_SAMPLES; + for (i = 0; i < sc->nrxchains; i++) { + cal = &sc->calib.adc_dc_offset[i]; + + dc_offset_mismatch_i = + (cal->pwr_meas_even_i - cal->pwr_meas_odd_i * 2) / count; + dc_offset_mismatch_q = + (cal->pwr_meas_odd_q - cal->pwr_meas_even_q * 2) / count; + + DPRINTFN(2, ("ADC DC offset calibration for chain %d\n", i)); + reg = AR_READ(sc, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); + reg = RW(reg, AR_PHY_NEW_ADC_DC_GAIN_QDC, + dc_offset_mismatch_q); + reg = RW(reg, AR_PHY_NEW_ADC_DC_GAIN_IDC, + dc_offset_mismatch_i); + AR_WRITE(sc, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), reg); + } + + /* Apply new settings. */ + AR_SETBITS(sc, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), + AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE); + AR_WRITE_BARRIER(sc); + + /* ADC DC offset calibration done. */ + sc->cur_calib_mask &= ~ATHN_CAL_ADC_DC; + memset(&sc->calib, 0, sizeof(sc->calib)); +} + +void +ar5008_write_txpower(struct athn_softc *sc, int16_t power[ATHN_POWER_COUNT]) +{ + AR_WRITE(sc, AR_PHY_POWER_TX_RATE1, + (power[ATHN_POWER_OFDM18 ] & 0x3f) << 24 | + (power[ATHN_POWER_OFDM12 ] & 0x3f) << 16 | + (power[ATHN_POWER_OFDM9 ] & 0x3f) << 8 | + (power[ATHN_POWER_OFDM6 ] & 0x3f)); + AR_WRITE(sc, AR_PHY_POWER_TX_RATE2, + (power[ATHN_POWER_OFDM54 ] & 0x3f) << 24 | + (power[ATHN_POWER_OFDM48 ] & 0x3f) << 16 | + (power[ATHN_POWER_OFDM36 ] & 0x3f) << 8 | + (power[ATHN_POWER_OFDM24 ] & 0x3f)); + AR_WRITE(sc, AR_PHY_POWER_TX_RATE3, + (power[ATHN_POWER_CCK2_SP ] & 0x3f) << 24 | + (power[ATHN_POWER_CCK2_LP ] & 0x3f) << 16 | + (power[ATHN_POWER_XR ] & 0x3f) << 8 | + (power[ATHN_POWER_CCK1_LP ] & 0x3f)); + AR_WRITE(sc, AR_PHY_POWER_TX_RATE4, + (power[ATHN_POWER_CCK11_SP] & 0x3f) << 24 | + (power[ATHN_POWER_CCK11_LP] & 0x3f) << 16 | + (power[ATHN_POWER_CCK55_SP] & 0x3f) << 8 | + (power[ATHN_POWER_CCK55_LP] & 0x3f)); + AR_WRITE(sc, AR_PHY_POWER_TX_RATE5, + (power[ATHN_POWER_HT20(3) ] & 0x3f) << 24 | + (power[ATHN_POWER_HT20(2) ] & 0x3f) << 16 | + (power[ATHN_POWER_HT20(1) ] & 0x3f) << 8 | + (power[ATHN_POWER_HT20(0) ] & 0x3f)); + AR_WRITE(sc, AR_PHY_POWER_TX_RATE6, + (power[ATHN_POWER_HT20(7) ] & 0x3f) << 24 | + (power[ATHN_POWER_HT20(6) ] & 0x3f) << 16 | + (power[ATHN_POWER_HT20(5) ] & 0x3f) << 8 | + (power[ATHN_POWER_HT20(4) ] & 0x3f)); + AR_WRITE(sc, AR_PHY_POWER_TX_RATE7, + (power[ATHN_POWER_HT40(3) ] & 0x3f) << 24 | + (power[ATHN_POWER_HT40(2) ] & 0x3f) << 16 | + (power[ATHN_POWER_HT40(1) ] & 0x3f) << 8 | + (power[ATHN_POWER_HT40(0) ] & 0x3f)); + AR_WRITE(sc, AR_PHY_POWER_TX_RATE8, + (power[ATHN_POWER_HT40(7) ] & 0x3f) << 24 | + (power[ATHN_POWER_HT40(6) ] & 0x3f) << 16 | + (power[ATHN_POWER_HT40(5) ] & 0x3f) << 8 | + (power[ATHN_POWER_HT40(4) ] & 0x3f)); + AR_WRITE(sc, AR_PHY_POWER_TX_RATE9, + (power[ATHN_POWER_OFDM_EXT] & 0x3f) << 24 | + (power[ATHN_POWER_CCK_EXT ] & 0x3f) << 16 | + (power[ATHN_POWER_OFDM_DUP] & 0x3f) << 8 | + (power[ATHN_POWER_CCK_DUP ] & 0x3f)); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_set_viterbi_mask(struct athn_softc *sc, int bin) +{ + uint32_t mask[4], reg; + uint8_t m[62], p[62]; /* XXX use bit arrays? */ + int i, bit, cur; + + /* Compute pilot mask. */ + cur = -6000; + for (i = 0; i < 4; i++) { + mask[i] = 0; + for (bit = 0; bit < 30; bit++) { + if (abs(cur - bin) < 100) + mask[i] |= 1 << bit; + cur += 100; + } + if (cur == 0) /* Skip entry "0". */ + cur = 100; + } + /* Write entries from -6000 to -3100. */ + AR_WRITE(sc, AR_PHY_TIMING7, mask[0]); + AR_WRITE(sc, AR_PHY_TIMING9, mask[0]); + /* Write entries from -3000 to -100. */ + AR_WRITE(sc, AR_PHY_TIMING8, mask[1]); + AR_WRITE(sc, AR_PHY_TIMING10, mask[1]); + /* Write entries from 100 to 3000. */ + AR_WRITE(sc, AR_PHY_PILOT_MASK_01_30, mask[2]); + AR_WRITE(sc, AR_PHY_CHANNEL_MASK_01_30, mask[2]); + /* Write entries from 3100 to 6000. */ + AR_WRITE(sc, AR_PHY_PILOT_MASK_31_60, mask[3]); + AR_WRITE(sc, AR_PHY_CHANNEL_MASK_31_60, mask[3]); + + /* Compute viterbi mask. */ + for (cur = 6100; cur >= 0; cur -= 100) + p[+cur / 100] = abs(cur - bin) < 75; + for (cur = -100; cur >= -6100; cur -= 100) + m[-cur / 100] = abs(cur - bin) < 75; + + /* Write viterbi mask (XXX needs to be reworked). */ + reg = + m[46] << 30 | m[47] << 28 | m[48] << 26 | m[49] << 24 | + m[50] << 22 | m[51] << 20 | m[52] << 18 | m[53] << 16 | + m[54] << 14 | m[55] << 12 | m[56] << 10 | m[57] << 8 | + m[58] << 6 | m[59] << 4 | m[60] << 2 | m[61] << 0; + AR_WRITE(sc, AR_PHY_BIN_MASK_1, reg); + AR_WRITE(sc, AR_PHY_VIT_MASK2_M_46_61, reg); + + /* XXX m[48] should be m[38] ? */ + reg = m[31] << 28 | m[32] << 26 | m[33] << 24 | + m[34] << 22 | m[35] << 20 | m[36] << 18 | m[37] << 16 | + m[48] << 14 | m[39] << 12 | m[40] << 10 | m[41] << 8 | + m[42] << 6 | m[43] << 4 | m[44] << 2 | m[45] << 0; + AR_WRITE(sc, AR_PHY_BIN_MASK_2, reg); + AR_WRITE(sc, AR_PHY_VIT_MASK2_M_31_45, reg); + + /* XXX This one is weird too. */ + reg = + m[16] << 30 | m[16] << 28 | m[18] << 26 | m[18] << 24 | + m[20] << 22 | m[20] << 20 | m[22] << 18 | m[22] << 16 | + m[24] << 14 | m[24] << 12 | m[25] << 10 | m[26] << 8 | + m[27] << 6 | m[28] << 4 | m[29] << 2 | m[30] << 0; + AR_WRITE(sc, AR_PHY_BIN_MASK_3, reg); + AR_WRITE(sc, AR_PHY_VIT_MASK2_M_16_30, reg); + + reg = + m[ 0] << 30 | m[ 1] << 28 | m[ 2] << 26 | m[ 3] << 24 | + m[ 4] << 22 | m[ 5] << 20 | m[ 6] << 18 | m[ 7] << 16 | + m[ 8] << 14 | m[ 9] << 12 | m[10] << 10 | m[11] << 8 | + m[12] << 6 | m[13] << 4 | m[14] << 2 | m[15] << 0; + AR_WRITE(sc, AR_PHY_MASK_CTL, reg); + AR_WRITE(sc, AR_PHY_VIT_MASK2_M_00_15, reg); + + reg = p[15] << 28 | p[14] << 26 | p[13] << 24 | + p[12] << 22 | p[11] << 20 | p[10] << 18 | p[ 9] << 16 | + p[ 8] << 14 | p[ 7] << 12 | p[ 6] << 10 | p[ 5] << 8 | + p[ 4] << 6 | p[ 3] << 4 | p[ 2] << 2 | p[ 1] << 0; + AR_WRITE(sc, AR_PHY_BIN_MASK2_1, reg); + AR_WRITE(sc, AR_PHY_VIT_MASK2_P_15_01, reg); + + reg = p[30] << 28 | p[29] << 26 | p[28] << 24 | + p[27] << 22 | p[26] << 20 | p[25] << 18 | p[24] << 16 | + p[23] << 14 | p[22] << 12 | p[21] << 10 | p[20] << 8 | + p[19] << 6 | p[18] << 4 | p[17] << 2 | p[16] << 0; + AR_WRITE(sc, AR_PHY_BIN_MASK2_2, reg); + AR_WRITE(sc, AR_PHY_VIT_MASK2_P_30_16, reg); + + reg = p[45] << 28 | p[44] << 26 | p[43] << 24 | + p[42] << 22 | p[41] << 20 | p[40] << 18 | p[39] << 16 | + p[38] << 14 | p[37] << 12 | p[36] << 10 | p[35] << 8 | + p[34] << 6 | p[33] << 4 | p[32] << 2 | p[31] << 0; + AR_WRITE(sc, AR_PHY_BIN_MASK2_3, reg); + AR_WRITE(sc, AR_PHY_VIT_MASK2_P_45_31, reg); + + reg = + p[61] << 30 | p[60] << 28 | p[59] << 26 | p[58] << 24 | + p[57] << 22 | p[56] << 20 | p[55] << 18 | p[54] << 16 | + p[53] << 14 | p[52] << 12 | p[51] << 10 | p[50] << 8 | + p[49] << 6 | p[48] << 4 | p[47] << 2 | p[46] << 0; + AR_WRITE(sc, AR_PHY_BIN_MASK2_4, reg); + AR_WRITE(sc, AR_PHY_VIT_MASK2_P_61_46, reg); + AR_WRITE_BARRIER(sc); +} + +void +ar5416_rw_rfbits(uint32_t *buf, int col, int off, uint32_t val, int nbits) +{ + int idx, bit; + + KASSERT(off >= 1 && col < 4 && nbits <= 32, "ar5416_rw_rfbits"); + + off--; /* Starts at 1. */ + while (nbits-- > 0) { + idx = off / 8; + bit = off % 8; + buf[idx] &= ~(1 << (bit + col * 8)); + buf[idx] |= ((val >> nbits) & 1) << (bit + col * 8); + off++; + } +} + +void +ar5416_rw_bank6tpc(struct athn_softc *sc, struct ieee80211_channel *c, + uint32_t *rwbank6tpc) +{ + const struct ar5416_eeprom *eep = sc->eep; + const struct ar5416_modal_eep_header *modal; + + if (IEEE80211_IS_CHAN_5GHZ(c)) { + modal = &eep->modalHeader[0]; + /* 5GHz db in column 0, bits [200-202]. */ + ar5416_rw_rfbits(rwbank6tpc, 0, 200, modal->db, 3); + /* 5GHz ob in column 0, bits [203-205]. */ + ar5416_rw_rfbits(rwbank6tpc, 0, 203, modal->ob, 3); + } else { + modal = &eep->modalHeader[1]; + /* 2GHz db in column 0, bits [194-196]. */ + ar5416_rw_rfbits(rwbank6tpc, 0, 194, modal->db, 3); + /* 2GHz ob in column 0, bits [197-199]. */ + ar5416_rw_rfbits(rwbank6tpc, 0, 197, modal->ob, 3); + } +} + +void +ar5416_reset_bb_gain(struct athn_softc *sc, struct ieee80211_channel *c) +{ + const uint32_t *pvals; + int i; + + if (IEEE80211_IS_CHAN_2GHZ(c)) + pvals = ar5416_bb_rfgain_vals_2g; + else + pvals = ar5416_bb_rfgain_vals_5g; + for (i = 0; i < 64; i++) + AR_WRITE(sc, AR_PHY_BB_RFGAIN(i), pvals[i]); +} + +void +ar5416_rf_reset(struct athn_softc *sc, struct ieee80211_channel *c) +{ + const uint32_t *bank6tpc; + int i; + + /* Bank 0. */ + AR_WRITE(sc, 0x98b0, 0x1e5795e5); + AR_WRITE(sc, 0x98e0, 0x02008020); + + /* Bank 1. */ + AR_WRITE(sc, 0x98b0, 0x02108421); + AR_WRITE(sc, 0x98ec, 0x00000008); + + /* Bank 2. */ + AR_WRITE(sc, 0x98b0, 0x0e73ff17); + AR_WRITE(sc, 0x98e0, 0x00000420); + + /* Bank 3. */ + if (IEEE80211_IS_CHAN_5GHZ(c)) + AR_WRITE(sc, 0x98f0, 0x01400018); + else + AR_WRITE(sc, 0x98f0, 0x01c00018); + + /* Select the Bank 6 TPC values to use. */ + if (AR_SREV_9160_10_OR_LATER(sc)) + bank6tpc = ar9160_bank6tpc_vals; + else + bank6tpc = ar5416_bank6tpc_vals; + if (sc->eep_rev >= AR_EEP_MINOR_VER_2) { + uint32_t *rwbank6tpc = sc->rwbuf; + + /* Copy values from .rodata to writable buffer. */ + memcpy(rwbank6tpc, bank6tpc, 32 * sizeof(uint32_t)); + ar5416_rw_bank6tpc(sc, c, rwbank6tpc); + bank6tpc = rwbank6tpc; + } + /* Bank 6 TPC. */ + for (i = 0; i < 32; i++) + AR_WRITE(sc, 0x989c, bank6tpc[i]); + if (IEEE80211_IS_CHAN_5GHZ(c)) + AR_WRITE(sc, 0x98d0, 0x0000000f); + else + AR_WRITE(sc, 0x98d0, 0x0010000f); + + /* Bank 7. */ + AR_WRITE(sc, 0x989c, 0x00000500); + AR_WRITE(sc, 0x989c, 0x00000800); + AR_WRITE(sc, 0x98cc, 0x0000000e); +} + +void +ar5416_reset_addac(struct athn_softc *sc, struct ieee80211_channel *c) +{ + const struct athn_addac *addac = sc->addac; + const uint32_t *pvals; + int i; + + // if (AR_SREV_9160(sc) && sc->eep_rev >= AR_EEP_MINOR_VER_7) { + // uint32_t *rwaddac = sc->rwbuf; + + // /* Copy values from .rodata to writable buffer. */ + // memcpy(rwaddac, addac->vals, addac->nvals * sizeof(uint32_t)); + // ar9160_rw_addac(sc, c, rwaddac); + // pvals = rwaddac; + // } else + pvals = addac->vals; + for (i = 0; i < addac->nvals; i++) + AR_WRITE(sc, 0x989c, pvals[i]); + AR_WRITE(sc, 0x98cc, 0); /* Finalize. */ +} + +void +ar5008_hw_init(struct athn_softc *sc, struct ieee80211_channel *c, + struct ieee80211_channel *extc) +{ + struct athn_ops *ops = &sc->ops; + const struct athn_ini *ini = sc->ini; + const uint32_t *pvals; + uint32_t reg; + int i; + + AR_WRITE(sc, AR_PHY(0), 0x00000007); + AR_WRITE(sc, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); + + if (!AR_SINGLE_CHIP(sc)) + ar5416_reset_addac(sc, c); + + AR_WRITE(sc, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); + + /* First initialization step (depends on channel band/bandwidth). */ + if (extc != NULL) { + if (IEEE80211_IS_CHAN_2GHZ(c)) + pvals = ini->vals_2g40; + else + pvals = ini->vals_5g40; + } else { + if (IEEE80211_IS_CHAN_2GHZ(c)) + pvals = ini->vals_2g20; + else + pvals = ini->vals_5g20; + } + DPRINTFN(4, ("writing modal init vals\n")); + for (i = 0; i < ini->nregs; i++) { + uint32_t val = pvals[i]; + + /* Fix AR_AN_TOP2 initialization value if required. */ + if (ini->regs[i] == AR_AN_TOP2 && + (sc->flags & ATHN_FLAG_AN_TOP2_FIXUP)) + val &= ~AR_AN_TOP2_PWDCLKIND; + AR_WRITE(sc, ini->regs[i], val); + if (AR_IS_ANALOG_REG(ini->regs[i])) { + AR_WRITE_BARRIER(sc); + DELAY(100); + } + if ((i & 0x1f) == 0) + DELAY(1); + } + AR_WRITE_BARRIER(sc); + + if (sc->rx_gain != NULL) + ar9280_reset_rx_gain(sc, c); + if (sc->tx_gain != NULL) + ar9280_reset_tx_gain(sc, c); + + if (AR_SREV_9271_10(sc)) { + AR_WRITE(sc, AR_PHY(68), 0x30002311); + AR_WRITE(sc, AR_PHY_RF_CTL3, 0x0a020001); + } + AR_WRITE_BARRIER(sc); + + /* Second initialization step (common to all channels). */ + DPRINTFN(4, ("writing common init vals\n")); + for (i = 0; i < ini->ncmregs; i++) { + AR_WRITE(sc, ini->cmregs[i], ini->cmvals[i]); + if (AR_IS_ANALOG_REG(ini->cmregs[i])) { + AR_WRITE_BARRIER(sc); + DELAY(100); + } + if ((i & 0x1f) == 0) + DELAY(1); + } + AR_WRITE_BARRIER(sc); + + if (!AR_SINGLE_CHIP(sc)) + ar5416_reset_bb_gain(sc, c); + + if (IEEE80211_IS_CHAN_5GHZ(c) && + (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK)) { + /* Update modal values for fast PLL clock. */ + if (extc != NULL) + pvals = ini->fastvals_5g40; + else + pvals = ini->fastvals_5g20; + DPRINTFN(4, ("writing fast pll clock init vals\n")); + for (i = 0; i < ini->nfastregs; i++) { + AR_WRITE(sc, ini->fastregs[i], pvals[i]); + if (AR_IS_ANALOG_REG(ini->fastregs[i])) { + AR_WRITE_BARRIER(sc); + DELAY(100); + } + if ((i & 0x1f) == 0) + DELAY(1); + } + } + + /* + * Set the RX_ABORT and RX_DIS bits to prevent frames with corrupted + * descriptor status. + */ + AR_SETBITS(sc, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT); + + /* Hardware workarounds for occasional Rx data corruption. */ + if (AR_SREV_9280_10_OR_LATER(sc)) { + reg = AR_READ(sc, AR_PCU_MISC_MODE2); + if (!AR_SREV_9271(sc)) + reg &= ~AR_PCU_MISC_MODE2_HWWAR1; + if (AR_SREV_9287_10_OR_LATER(sc)) + reg &= ~AR_PCU_MISC_MODE2_HWWAR2; + AR_WRITE(sc, AR_PCU_MISC_MODE2, reg); + + } else if (AR_SREV_5416_20_OR_LATER(sc)) { + /* Disable baseband clock gating. */ + AR_WRITE(sc, AR_PHY(651), 0x11); + + if (AR_SREV_9160(sc)) { + /* Disable RIFS search to fix baseband hang. */ + AR_CLRBITS(sc, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, + AR_PHY_RIFS_INIT_DELAY_M); + } + } + AR_WRITE_BARRIER(sc); + + ar5008_set_phy(sc, c, extc); + ar5008_init_chains(sc); + + if (sc->flags & ATHN_FLAG_OLPC) { + // extern int ticks; + sc->olpc_ticks = ticks; + ops->olpc_init(sc); + } + + ops->set_txpower(sc, c, extc); + + if (!AR_SINGLE_CHIP(sc)) + ar5416_rf_reset(sc, c); +} + +uint8_t +ar5008_get_vpd(uint8_t pwr, const uint8_t *pwrPdg, const uint8_t *vpdPdg, + int nicepts) +{ + uint8_t vpd; + int i, lo, hi; + + for (i = 0; i < nicepts; i++) + if (pwrPdg[i] > pwr) + break; + hi = i; + lo = hi - 1; + if (lo == -1) + lo = hi; + else if (hi == nicepts) + hi = lo; + + vpd = athn_interpolate(pwr, pwrPdg[lo], vpdPdg[lo], + pwrPdg[hi], vpdPdg[hi]); + return (vpd); +} + +void +ar5008_get_pdadcs(struct athn_softc *sc, uint8_t fbin, + struct athn_pier *lopier, struct athn_pier *hipier, int nxpdgains, + int nicepts, uint8_t overlap, uint8_t *boundaries, uint8_t *pdadcs) +{ +#define DB(x) ((x) / 2) /* Convert half dB to dB. */ + uint8_t minpwr[AR_PD_GAINS_IN_MASK], maxpwr[AR_PD_GAINS_IN_MASK]; + uint8_t vpd[AR_MAX_PWR_RANGE_IN_HALF_DB], pwr; + uint8_t lovpd, hivpd, boundary; + int16_t ss, delta, vpdstep, val; + int i, j, npdadcs, nvpds, maxidx, tgtidx; + + /* Compute min and max power in half dB for each pdGain. */ + for (i = 0; i < nxpdgains; i++) { + minpwr[i] = MAX(lopier->pwr[i][0], hipier->pwr[i][0]); + maxpwr[i] = MIN(lopier->pwr[i][nicepts - 1], + hipier->pwr[i][nicepts - 1]); + } + + /* Fill phase domain analog-to-digital converter (PDADC) table. */ + npdadcs = 0; + for (i = 0; i < nxpdgains; i++) { + if (i != nxpdgains - 1) + boundaries[i] = DB(maxpwr[i] + minpwr[i + 1]) / 2; + else + boundaries[i] = DB(maxpwr[i]); + if (boundaries[i] > AR_MAX_RATE_POWER) + boundaries[i] = AR_MAX_RATE_POWER; + + if (i == 0 && !AR_SREV_5416_20_OR_LATER(sc)) { + /* Fix the gain delta (AR5416 1.0 only). */ + delta = boundaries[0] - 23; + boundaries[0] = 23; + } else + delta = 0; + + /* Find starting index for this pdGain. */ + if (i != 0) { + ss = boundaries[i - 1] - DB(minpwr[i]) - + overlap + 1 + delta; + } else if (AR_SREV_9280_10_OR_LATER(sc)) { + ss = -DB(minpwr[i]); + } else + ss = 0; + + /* Compute Vpd table for this pdGain. */ + nvpds = DB(maxpwr[i] - minpwr[i]) + 1; + memset(vpd, 0, sizeof(vpd)); + pwr = minpwr[i]; + for (j = 0; j < nvpds; j++) { + /* Get lower and higher Vpd. */ + lovpd = ar5008_get_vpd(pwr, lopier->pwr[i], + lopier->vpd[i], nicepts); + hivpd = ar5008_get_vpd(pwr, hipier->pwr[i], + hipier->vpd[i], nicepts); + + /* Interpolate the final Vpd. */ + vpd[j] = athn_interpolate(fbin, + lopier->fbin, lovpd, hipier->fbin, hivpd); + + pwr += 2; /* In half dB. */ + } + + /* Extrapolate data for ss < 0. */ + if (vpd[1] > vpd[0]) + vpdstep = vpd[1] - vpd[0]; + else + vpdstep = 1; + while (ss < 0 && npdadcs < AR_NUM_PDADC_VALUES - 1) { + val = vpd[0] + ss * vpdstep; + pdadcs[npdadcs++] = MAX(val, 0); + ss++; + } + + tgtidx = boundaries[i] + overlap - DB(minpwr[i]); + maxidx = MIN(tgtidx, nvpds); + while (ss < maxidx && npdadcs < AR_NUM_PDADC_VALUES - 1) + pdadcs[npdadcs++] = vpd[ss++]; + + if (tgtidx < maxidx) + continue; + + /* Extrapolate data for maxidx <= ss <= tgtidx. */ + if (vpd[nvpds - 1] > vpd[nvpds - 2]) + vpdstep = vpd[nvpds - 1] - vpd[nvpds - 2]; + else + vpdstep = 1; + while (ss <= tgtidx && npdadcs < AR_NUM_PDADC_VALUES - 1) { + val = vpd[nvpds - 1] + (ss - maxidx + 1) * vpdstep; + pdadcs[npdadcs++] = MIN(val, 255); + ss++; + } + } + + /* Fill remaining PDADC and boundaries entries. */ + if (AR_SREV_9285(sc)) + boundary = AR9285_PD_GAIN_BOUNDARY_DEFAULT; + else /* Fill with latest. */ + boundary = boundaries[nxpdgains - 1]; + + for (; nxpdgains < AR_PD_GAINS_IN_MASK; nxpdgains++) + boundaries[nxpdgains] = boundary; + + for (; npdadcs < AR_NUM_PDADC_VALUES; npdadcs++) + pdadcs[npdadcs] = pdadcs[npdadcs - 1]; +#undef DB +} + +void +ar5008_get_lg_tpow(struct athn_softc *sc, struct ieee80211_channel *c, + uint8_t ctl, const struct ar_cal_target_power_leg *tgt, int nchans, + uint8_t tpow[4]) +{ + uint8_t fbin; + int i, lo, hi; + + /* Find interval (lower and upper indices). */ + fbin = athn_chan2fbin(c); + for (i = 0; i < nchans; i++) { + if (tgt[i].bChannel == AR_BCHAN_UNUSED || + tgt[i].bChannel > fbin) + break; + } + hi = i; + lo = hi - 1; + if (lo == -1) + lo = hi; + else if (hi == nchans || tgt[hi].bChannel == AR_BCHAN_UNUSED) + hi = lo; + + /* Interpolate values. */ + for (i = 0; i < 4; i++) { + tpow[i] = athn_interpolate(fbin, + tgt[lo].bChannel, tgt[lo].tPow2x[i], + tgt[hi].bChannel, tgt[hi].tPow2x[i]); + } + /* XXX Apply conformance testing limit. */ +} + +void +ar5008_get_ht_tpow(struct athn_softc *sc, struct ieee80211_channel *c, + uint8_t ctl, const struct ar_cal_target_power_ht *tgt, int nchans, + uint8_t tpow[8]) +{ + uint8_t fbin; + int i, lo, hi; + + /* Find interval (lower and upper indices). */ + fbin = athn_chan2fbin(c); + for (i = 0; i < nchans; i++) { + if (tgt[i].bChannel == AR_BCHAN_UNUSED || + tgt[i].bChannel > fbin) + break; + } + hi = i; + lo = hi - 1; + if (lo == -1) + lo = hi; + else if (hi == nchans || tgt[hi].bChannel == AR_BCHAN_UNUSED) + hi = lo; + + /* Interpolate values. */ + for (i = 0; i < 8; i++) { + tpow[i] = athn_interpolate(fbin, + tgt[lo].bChannel, tgt[lo].tPow2x[i], + tgt[hi].bChannel, tgt[hi].tPow2x[i]); + } + /* XXX Apply conformance testing limit. */ +} + +/* + * Adaptive noise immunity. + */ +void +ar5008_set_noise_immunity_level(struct athn_softc *sc, int level) +{ + int high = level == 4; + uint32_t reg; + + reg = AR_READ(sc, AR_PHY_DESIRED_SZ); + reg = RW(reg, AR_PHY_DESIRED_SZ_TOT_DES, high ? -62 : -55); + AR_WRITE(sc, AR_PHY_DESIRED_SZ, reg); + + reg = AR_READ(sc, AR_PHY_AGC_CTL1); + reg = RW(reg, AR_PHY_AGC_CTL1_COARSE_LOW, high ? -70 : -64); + reg = RW(reg, AR_PHY_AGC_CTL1_COARSE_HIGH, high ? -12 : -14); + AR_WRITE(sc, AR_PHY_AGC_CTL1, reg); + + reg = AR_READ(sc, AR_PHY_FIND_SIG); + reg = RW(reg, AR_PHY_FIND_SIG_FIRPWR, high ? -80 : -78); + AR_WRITE(sc, AR_PHY_FIND_SIG, reg); + + AR_WRITE_BARRIER(sc); +} + +void +ar5008_enable_ofdm_weak_signal(struct athn_softc *sc) +{ + uint32_t reg; + + reg = AR_READ(sc, AR_PHY_SFCORR_LOW); + reg = RW(reg, AR_PHY_SFCORR_LOW_M1_THRESH_LOW, 50); + reg = RW(reg, AR_PHY_SFCORR_LOW_M2_THRESH_LOW, 40); + reg = RW(reg, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, 48); + AR_WRITE(sc, AR_PHY_SFCORR_LOW, reg); + + reg = AR_READ(sc, AR_PHY_SFCORR); + reg = RW(reg, AR_PHY_SFCORR_M1_THRESH, 77); + reg = RW(reg, AR_PHY_SFCORR_M2_THRESH, 64); + reg = RW(reg, AR_PHY_SFCORR_M2COUNT_THR, 16); + AR_WRITE(sc, AR_PHY_SFCORR, reg); + + reg = AR_READ(sc, AR_PHY_SFCORR_EXT); + reg = RW(reg, AR_PHY_SFCORR_EXT_M1_THRESH_LOW, 50); + reg = RW(reg, AR_PHY_SFCORR_EXT_M2_THRESH_LOW, 40); + reg = RW(reg, AR_PHY_SFCORR_EXT_M1_THRESH, 77); + reg = RW(reg, AR_PHY_SFCORR_EXT_M2_THRESH, 64); + AR_WRITE(sc, AR_PHY_SFCORR_EXT, reg); + + AR_SETBITS(sc, AR_PHY_SFCORR_LOW, + AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_disable_ofdm_weak_signal(struct athn_softc *sc) +{ + uint32_t reg; + + reg = AR_READ(sc, AR_PHY_SFCORR_LOW); + reg = RW(reg, AR_PHY_SFCORR_LOW_M1_THRESH_LOW, 127); + reg = RW(reg, AR_PHY_SFCORR_LOW_M2_THRESH_LOW, 127); + reg = RW(reg, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, 63); + AR_WRITE(sc, AR_PHY_SFCORR_LOW, reg); + + reg = AR_READ(sc, AR_PHY_SFCORR); + reg = RW(reg, AR_PHY_SFCORR_M1_THRESH, 127); + reg = RW(reg, AR_PHY_SFCORR_M2_THRESH, 127); + reg = RW(reg, AR_PHY_SFCORR_M2COUNT_THR, 31); + AR_WRITE(sc, AR_PHY_SFCORR, reg); + + reg = AR_READ(sc, AR_PHY_SFCORR_EXT); + reg = RW(reg, AR_PHY_SFCORR_EXT_M1_THRESH_LOW, 127); + reg = RW(reg, AR_PHY_SFCORR_EXT_M2_THRESH_LOW, 127); + reg = RW(reg, AR_PHY_SFCORR_EXT_M1_THRESH, 127); + reg = RW(reg, AR_PHY_SFCORR_EXT_M2_THRESH, 127); + AR_WRITE(sc, AR_PHY_SFCORR_EXT, reg); + + AR_CLRBITS(sc, AR_PHY_SFCORR_LOW, + AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_set_cck_weak_signal(struct athn_softc *sc, int high) +{ + uint32_t reg; + + reg = AR_READ(sc, AR_PHY_CCK_DETECT); + reg = RW(reg, AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, high ? 6 : 8); + AR_WRITE(sc, AR_PHY_CCK_DETECT, reg); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_set_firstep_level(struct athn_softc *sc, int level) +{ + uint32_t reg; + + reg = AR_READ(sc, AR_PHY_FIND_SIG); + reg = RW(reg, AR_PHY_FIND_SIG_FIRSTEP, level * 4); + AR_WRITE(sc, AR_PHY_FIND_SIG, reg); + AR_WRITE_BARRIER(sc); +} + +void +ar5008_set_spur_immunity_level(struct athn_softc *sc, int level) +{ + uint32_t reg; + + reg = AR_READ(sc, AR_PHY_TIMING5); + reg = RW(reg, AR_PHY_TIMING5_CYCPWR_THR1, (level + 1) * 2); + AR_WRITE(sc, AR_PHY_TIMING5, reg); + AR_WRITE_BARRIER(sc); +} diff --git a/sys/dev/athn/ar9280.c b/sys/dev/athn/ar9280.c new file mode 100644 --- /dev/null +++ b/sys/dev/athn/ar9280.c @@ -0,0 +1,626 @@ +/* $OpenBSD: ar9280.c,v 1.28 2021/04/15 18:25:43 stsp Exp $ */ + +/*- + * Copyright (c) 2009 Damien Bergamini + * Copyright (c) 2008-2009 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Driver for Atheros 802.11a/g/n chipsets. + * Routines for AR9220, AR9223, AR9280 and AR9281 chipsets. + */ + +// #include "bpfilter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#include +// #include +#include + +#include +// #include + +#if NBPFILTER > 0 +#include +#endif +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "athnreg.h" +#include "athnvar.h" + +#include "ar5008reg.h" +#include "ar5416reg.h" /* We share the ROM layout. */ +#include "ar9280reg.h" + +int ar9280_attach(struct athn_softc *); +// void ar9280_setup(struct athn_softc *); +int ar9280_set_synth(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +void ar9280_init_from_rom(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +void ar9280_spur_mitigate(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +void ar9280_olpc_get_pdadcs(struct athn_softc *, + struct ieee80211_channel *, int, uint8_t *, uint8_t *, uint8_t *); +void ar9280_reset_rx_gain(struct athn_softc *, struct ieee80211_channel *); +void ar9280_reset_tx_gain(struct athn_softc *, struct ieee80211_channel *); +void ar9280_olpc_init(struct athn_softc *); +void ar9280_olpc_temp_compensation(struct athn_softc *); + +/* Extern functions. */ +uint8_t athn_chan2fbin(struct ieee80211_channel *); +void athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, int *); +int ar5008_attach(struct athn_softc *); +void ar5008_set_viterbi_mask(struct athn_softc *, int); +// void ar5416_swap_rom(struct athn_softc *); +// void ar5416_set_txpower(struct athn_softc *, struct ieee80211_channel *, +// struct ieee80211_channel *); +// const struct ar_spur_chan * +// ar5416_get_spur_chans(struct athn_softc *, int); + + +// Not needed +int +ar9280_attach(struct athn_softc *sc) +{ + // sc->eep_base = AR5416_EEP_START_LOC; + // sc->eep_size = sizeof(struct ar5416_eeprom); + // sc->ngpiopins = (sc->flags & ATHN_FLAG_USB) ? 16 : 10; + // sc->led_pin = 1; + // sc->workaround = AR9280_WA_DEFAULT; + // // sc->ops.setup = ar9280_setup; + // // sc->ops.swap_rom = ar5416_swap_rom; + // // sc->ops.init_from_rom = ar9280_init_from_rom; + // // sc->ops.set_txpower = ar5416_set_txpower; + // sc->ops.set_synth = ar9280_set_synth; + // sc->ops.spur_mitigate = ar9280_spur_mitigate; + // // sc->ops.get_spur_chans = ar5416_get_spur_chans; + // sc->ops.olpc_init = ar9280_olpc_init; + // sc->ops.olpc_temp_compensation = ar9280_olpc_temp_compensation; + // sc->cca_min_2g = AR9280_PHY_CCA_MIN_GOOD_VAL_2GHZ; + // sc->cca_max_2g = AR9280_PHY_CCA_MAX_GOOD_VAL_2GHZ; + // sc->cca_min_5g = AR9280_PHY_CCA_MIN_GOOD_VAL_5GHZ; + // sc->cca_max_5g = AR9280_PHY_CCA_MAX_GOOD_VAL_5GHZ; + // sc->ini = &ar9280_2_0_ini; + // sc->serdes = &ar9280_2_0_serdes; + + return (ar5008_attach(sc)); +} + +// void +// ar9280_setup(struct athn_softc *sc) +// { +// const struct ar5416_eeprom *eep = sc->eep; +// uint8_t type; + +// /* Determine if open loop power control should be used. */ +// if (sc->eep_rev >= AR_EEP_MINOR_VER_19 && +// eep->baseEepHeader.openLoopPwrCntl) +// sc->flags |= ATHN_FLAG_OLPC; + +// /* Determine if fast PLL clock is supported. */ +// if (AR_SREV_9280_20(sc) && +// (sc->eep_rev <= AR_EEP_MINOR_VER_16 || +// eep->baseEepHeader.fastClk5g)) +// sc->flags |= ATHN_FLAG_FAST_PLL_CLOCK; + +// /* +// * Determine if initialization value for AR_AN_TOP2 must be fixed. +// * This is required for some AR9220 devices such as Ubiquiti SR71-12. +// */ +// if (AR_SREV_9280_20(sc) && +// sc->eep_rev > AR_EEP_MINOR_VER_10 && +// !eep->baseEepHeader.pwdclkind) { +// DPRINTF(("AR_AN_TOP2 fixup required\n")); +// sc->flags |= ATHN_FLAG_AN_TOP2_FIXUP; +// } + +// if (AR_SREV_9280_20(sc)) { +// /* Check if we have a valid rxGainType field in ROM. */ +// if (sc->eep_rev >= AR_EEP_MINOR_VER_17) { +// /* Select initialization values based on ROM. */ +// type = eep->baseEepHeader.rxGainType; +// DPRINTF(("Rx gain type=0x%x\n", type)); +// if (type == AR5416_EEP_RXGAIN_23DB_BACKOFF) +// sc->rx_gain = &ar9280_2_0_rx_gain_23db_backoff; +// else if (type == AR5416_EEP_RXGAIN_13DB_BACKOFF) +// sc->rx_gain = &ar9280_2_0_rx_gain_13db_backoff; +// else +// sc->rx_gain = &ar9280_2_0_rx_gain; +// } else +// sc->rx_gain = &ar9280_2_0_rx_gain; + +// /* Check if we have a valid txGainType field in ROM. */ +// if (sc->eep_rev >= AR_EEP_MINOR_VER_19) { +// /* Select initialization values based on ROM. */ +// type = eep->baseEepHeader.txGainType; +// DPRINTF(("Tx gain type=0x%x\n", type)); +// if (type == AR_EEP_TXGAIN_HIGH_POWER) +// sc->tx_gain = &ar9280_2_0_tx_gain_high_power; +// else +// sc->tx_gain = &ar9280_2_0_tx_gain; +// } else +// sc->tx_gain = &ar9280_2_0_tx_gain; +// } +// } + +int +ar9280_set_synth(struct athn_softc *sc, struct ieee80211_channel *c, + struct ieee80211_channel *extc) +{ + uint32_t phy, reg, ndiv = 0; + uint32_t freq = c->ic_freq; + + phy = AR_READ(sc, AR9280_PHY_SYNTH_CONTROL) & ~0x3fffffff; + + if (IEEE80211_IS_CHAN_2GHZ(c)) { + phy |= (freq << 16) / 15; + phy |= AR9280_BMODE | AR9280_FRACMODE; + + if (AR_SREV_9287_11_OR_LATER(sc)) { + /* NB: Magic values from the Linux driver. */ + if (freq == 2484) { /* Channel 14. */ + /* Japanese regulatory requirements. */ + AR_WRITE(sc, AR_PHY(637), 0x00000000); + AR_WRITE(sc, AR_PHY(638), 0xefff0301); + AR_WRITE(sc, AR_PHY(639), 0xca9228ee); + } else { + AR_WRITE(sc, AR_PHY(637), 0x00fffeff); + AR_WRITE(sc, AR_PHY(638), 0x00f5f9ff); + AR_WRITE(sc, AR_PHY(639), 0xb79f6427); + } + } else { + reg = AR_READ(sc, AR_PHY_CCK_TX_CTRL); + if (freq == 2484) /* Channel 14. */ + reg |= AR_PHY_CCK_TX_CTRL_JAPAN; + else + reg &= ~AR_PHY_CCK_TX_CTRL_JAPAN; + AR_WRITE(sc, AR_PHY_CCK_TX_CTRL, reg); + } + } else { + if (AR_SREV_9285_10_OR_LATER(sc) || + sc->eep_rev < AR_EEP_MINOR_VER_22 || + !((struct ar5416_base_eep_header *)sc->eep)->frac_n_5g) { + if ((freq % 20) == 0) { + ndiv = (freq * 3) / 60; + phy |= SM(AR9280_AMODE_REFSEL, 3); + } else if ((freq % 10) == 0) { + ndiv = (freq * 6) / 60; + phy |= SM(AR9280_AMODE_REFSEL, 2); + } + } + if (ndiv != 0) { + phy |= (ndiv & 0x1ff) << 17; + phy |= (ndiv & ~0x1ff) * 2; + } else { + phy |= (freq << 15) / 15; + phy |= AR9280_FRACMODE; + + reg = AR_READ(sc, AR_AN_SYNTH9); + reg = RW(reg, AR_AN_SYNTH9_REFDIVA, 1); + AR_WRITE(sc, AR_AN_SYNTH9, reg); + } + } + AR_WRITE_BARRIER(sc); + DPRINTFN(4, ("AR9280_PHY_SYNTH_CONTROL=0x%08x\n", phy)); + AR_WRITE(sc, AR9280_PHY_SYNTH_CONTROL, phy); + AR_WRITE_BARRIER(sc); + return (0); +} + +// Not needed +// void +// ar9280_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c, +// struct ieee80211_channel *extc) +// { +// static const uint32_t chainoffset[] = { 0x0000, 0x2000, 0x1000 }; +// const struct ar5416_eeprom *eep = sc->eep; +// const struct ar5416_modal_eep_header *modal; +// uint32_t reg, offset; +// uint8_t txRxAtten; +// int i; + +// modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)]; + +// AR_WRITE(sc, AR_PHY_SWITCH_COM, modal->antCtrlCommon); + +// for (i = 0; i < AR9280_MAX_CHAINS; i++) { +// if (sc->rxchainmask == 0x5 || sc->txchainmask == 0x5) +// offset = chainoffset[i]; +// else +// offset = i * 0x1000; + +// AR_WRITE(sc, AR_PHY_SWITCH_CHAIN_0 + offset, +// modal->antCtrlChain[i]); + +// reg = AR_READ(sc, AR_PHY_TIMING_CTRL4_0 + offset); +// reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, +// modal->iqCalICh[i]); +// reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, +// modal->iqCalQCh[i]); +// AR_WRITE(sc, AR_PHY_TIMING_CTRL4_0 + offset, reg); + +// if (sc->eep_rev >= AR_EEP_MINOR_VER_3) { +// reg = AR_READ(sc, AR_PHY_GAIN_2GHZ + offset); +// reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, +// modal->bswMargin[i]); +// reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_DB, +// modal->bswAtten[i]); +// reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, +// modal->xatten2Margin[i]); +// reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_DB, +// modal->xatten2Db[i]); +// AR_WRITE(sc, AR_PHY_GAIN_2GHZ + offset, reg); +// } +// if (sc->eep_rev >= AR_EEP_MINOR_VER_3) +// txRxAtten = modal->txRxAttenCh[i]; +// else /* Workaround for ROM versions < 14.3. */ +// txRxAtten = IEEE80211_IS_CHAN_2GHZ(c) ? 23 : 44; +// reg = AR_READ(sc, AR_PHY_RXGAIN + offset); +// reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_ATTEN, +// txRxAtten); +// reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_MARGIN, +// modal->rxTxMarginCh[i]); +// AR_WRITE(sc, AR_PHY_RXGAIN + offset, reg); +// } +// if (IEEE80211_IS_CHAN_2GHZ(c)) { +// reg = AR_READ(sc, AR_AN_RF2G1_CH0); +// reg = RW(reg, AR_AN_RF2G1_CH0_OB, modal->ob); +// reg = RW(reg, AR_AN_RF2G1_CH0_DB, modal->db); +// AR_WRITE(sc, AR_AN_RF2G1_CH0, reg); +// AR_WRITE_BARRIER(sc); +// DELAY(100); + +// reg = AR_READ(sc, AR_AN_RF2G1_CH1); +// reg = RW(reg, AR_AN_RF2G1_CH1_OB, modal->ob_ch1); +// reg = RW(reg, AR_AN_RF2G1_CH1_DB, modal->db_ch1); +// AR_WRITE(sc, AR_AN_RF2G1_CH1, reg); +// AR_WRITE_BARRIER(sc); +// DELAY(100); +// } else { +// reg = AR_READ(sc, AR_AN_RF5G1_CH0); +// reg = RW(reg, AR_AN_RF5G1_CH0_OB5, modal->ob); +// reg = RW(reg, AR_AN_RF5G1_CH0_DB5, modal->db); +// AR_WRITE(sc, AR_AN_RF5G1_CH0, reg); +// AR_WRITE_BARRIER(sc); +// DELAY(100); + +// reg = AR_READ(sc, AR_AN_RF5G1_CH1); +// reg = RW(reg, AR_AN_RF5G1_CH1_OB5, modal->ob_ch1); +// reg = RW(reg, AR_AN_RF5G1_CH1_DB5, modal->db_ch1); +// AR_WRITE(sc, AR_AN_RF5G1_CH1, reg); +// AR_WRITE_BARRIER(sc); +// DELAY(100); +// } +// reg = AR_READ(sc, AR_AN_TOP2); +// if ((sc->flags & ATHN_FLAG_USB) && IEEE80211_IS_CHAN_5GHZ(c)) { +// /* +// * Hardcode the output voltage of x-PA bias LDO to the +// * lowest value for UB94 such that the card doesn't get +// * too hot. +// */ +// reg = RW(reg, AR_AN_TOP2_XPABIAS_LVL, 0); +// } else +// reg = RW(reg, AR_AN_TOP2_XPABIAS_LVL, modal->xpaBiasLvl); +// if (modal->flagBits & AR5416_EEP_FLAG_LOCALBIAS) +// reg |= AR_AN_TOP2_LOCALBIAS; +// else +// reg &= ~AR_AN_TOP2_LOCALBIAS; +// AR_WRITE(sc, AR_AN_TOP2, reg); +// AR_WRITE_BARRIER(sc); +// DELAY(100); + +// reg = AR_READ(sc, AR_PHY_XPA_CFG); +// if (modal->flagBits & AR5416_EEP_FLAG_FORCEXPAON) +// reg |= AR_PHY_FORCE_XPA_CFG; +// else +// reg &= ~AR_PHY_FORCE_XPA_CFG; +// AR_WRITE(sc, AR_PHY_XPA_CFG, reg); + +// reg = AR_READ(sc, AR_PHY_SETTLING); +// reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->switchSettling); +// AR_WRITE(sc, AR_PHY_SETTLING, reg); + +// reg = AR_READ(sc, AR_PHY_DESIRED_SZ); +// reg = RW(reg, AR_PHY_DESIRED_SZ_ADC, modal->adcDesiredSize); +// AR_WRITE(sc, AR_PHY_DESIRED_SZ, reg); + +// reg = SM(AR_PHY_RF_CTL4_TX_END_XPAA_OFF, modal->txEndToXpaOff); +// reg |= SM(AR_PHY_RF_CTL4_TX_END_XPAB_OFF, modal->txEndToXpaOff); +// reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAA_ON, modal->txFrameToXpaOn); +// reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAB_ON, modal->txFrameToXpaOn); +// AR_WRITE(sc, AR_PHY_RF_CTL4, reg); + +// reg = AR_READ(sc, AR_PHY_RF_CTL3); +// reg = RW(reg, AR_PHY_TX_END_TO_A2_RX_ON, modal->txEndToRxOn); +// AR_WRITE(sc, AR_PHY_RF_CTL3, reg); + +// reg = AR_READ(sc, AR_PHY_CCA(0)); +// reg = RW(reg, AR9280_PHY_CCA_THRESH62, modal->thresh62); +// AR_WRITE(sc, AR_PHY_CCA(0), reg); + +// reg = AR_READ(sc, AR_PHY_EXT_CCA0); +// reg = RW(reg, AR_PHY_EXT_CCA0_THRESH62, modal->thresh62); +// AR_WRITE(sc, AR_PHY_EXT_CCA0, reg); + +// if (sc->eep_rev >= AR_EEP_MINOR_VER_2) { +// reg = AR_READ(sc, AR_PHY_RF_CTL2); +// reg = RW(reg, AR_PHY_TX_END_DATA_START, +// modal->txFrameToDataStart); +// reg = RW(reg, AR_PHY_TX_END_PA_ON, modal->txFrameToPaOn); +// AR_WRITE(sc, AR_PHY_RF_CTL2, reg); +// } +// if (sc->eep_rev >= AR_EEP_MINOR_VER_3 && extc != NULL) { +// /* Overwrite switch settling with HT-40 value. */ +// reg = AR_READ(sc, AR_PHY_SETTLING); +// reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->swSettleHt40); +// AR_WRITE(sc, AR_PHY_SETTLING, reg); +// } +// if (sc->eep_rev >= AR_EEP_MINOR_VER_19) { +// reg = AR_READ(sc, AR_PHY_CCK_TX_CTRL); +// reg = RW(reg, AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK, +// MS(modal->miscBits, AR5416_EEP_MISC_TX_DAC_SCALE_CCK)); +// AR_WRITE(sc, AR_PHY_CCK_TX_CTRL, reg); +// } +// if (AR_SREV_9280_20(sc) && +// sc->eep_rev >= AR_EEP_MINOR_VER_20) { +// reg = AR_READ(sc, AR_AN_TOP1); +// if (eep->baseEepHeader.dacLpMode && +// (IEEE80211_IS_CHAN_2GHZ(c) || +// !eep->baseEepHeader.dacHiPwrMode_5G)) +// reg |= AR_AN_TOP1_DACLPMODE; +// else +// reg &= ~AR_AN_TOP1_DACLPMODE; +// AR_WRITE(sc, AR_AN_TOP1, reg); +// AR_WRITE_BARRIER(sc); +// DELAY(100); + +// reg = AR_READ(sc, AR_PHY_FRAME_CTL); +// reg = RW(reg, AR_PHY_FRAME_CTL_TX_CLIP, +// MS(modal->miscBits, AR5416_EEP_MISC_TX_CLIP)); +// AR_WRITE(sc, AR_PHY_FRAME_CTL, reg); + +// reg = AR_READ(sc, AR_PHY_TX_PWRCTRL9); +// reg = RW(reg, AR_PHY_TX_DESIRED_SCALE_CCK, +// eep->baseEepHeader.desiredScaleCCK); +// AR_WRITE(sc, AR_PHY_TX_PWRCTRL9, reg); +// } +// AR_WRITE_BARRIER(sc); +// } + +// void +// ar9280_olpc_get_pdadcs(struct athn_softc *sc, struct ieee80211_channel *c, +// int chain, uint8_t *boundaries, uint8_t *pdadcs, uint8_t *txgain) +// { +// const struct ar5416_eeprom *eep = sc->eep; +// const struct ar_cal_data_per_freq_olpc *pierdata; +// const uint8_t *pierfreq; +// uint8_t fbin, pcdac, pwr, idx; +// int i, lo, hi, npiers; + +// if (IEEE80211_IS_CHAN_2GHZ(c)) { +// pierfreq = eep->calFreqPier2G; +// pierdata = (const struct ar_cal_data_per_freq_olpc *) +// eep->calPierData2G[chain]; +// npiers = AR5416_NUM_2G_CAL_PIERS; +// } else { +// pierfreq = eep->calFreqPier5G; +// pierdata = (const struct ar_cal_data_per_freq_olpc *) +// eep->calPierData5G[chain]; +// npiers = AR5416_NUM_5G_CAL_PIERS; +// } +// /* Find channel in ROM pier table. */ +// fbin = athn_chan2fbin(c); +// athn_get_pier_ival(fbin, pierfreq, npiers, &lo, &hi); + +// /* Get average. */ +// pwr = (pierdata[lo].pwrPdg[0][0] + pierdata[hi].pwrPdg[0][0]) / 2; +// pwr /= 2; /* Convert to dB. */ + +// /* Find power control digital-to-analog converter (PCDAC) value. */ +// pcdac = pierdata[hi].pcdac[0][0]; +// for (idx = 0; idx < AR9280_TX_GAIN_TABLE_SIZE - 1; idx++) +// if (pcdac <= sc->tx_gain_tbl[idx]) +// break; +// *txgain = idx; + +// DPRINTFN(3, ("fbin=%d lo=%d hi=%d pwr=%d pcdac=%d txgain=%d\n", +// fbin, lo, hi, pwr, pcdac, idx)); + +// /* Fill phase domain analog-to-digital converter (PDADC) table. */ +// for (i = 0; i < AR_NUM_PDADC_VALUES; i++) +// pdadcs[i] = (i < pwr) ? 0x00 : 0xff; + +// for (i = 0; i < AR_PD_GAINS_IN_MASK; i++) +// boundaries[i] = AR9280_PD_GAIN_BOUNDARY_DEFAULT; +// } + +void +ar9280_spur_mitigate(struct athn_softc *sc, struct ieee80211_channel *c, + struct ieee80211_channel *extc) +{ + const struct ar_spur_chan *spurchans; + int spur, bin, spur_delta_phase, spur_freq_sd, spur_subchannel_sd; + int spur_off, range, i; + + /* NB: Always clear. */ + AR_CLRBITS(sc, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); + + range = (extc != NULL) ? 19 : 10; + + spurchans = sc->ops.get_spur_chans(sc, IEEE80211_IS_CHAN_2GHZ(c)); + for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { + spur = spurchans[i].spurChan; + if (spur == AR_NO_SPUR) + return; /* XXX disable if it was enabled! */ + spur /= 10; + if (IEEE80211_IS_CHAN_2GHZ(c)) + spur += AR_BASE_FREQ_2GHZ; + else + spur += AR_BASE_FREQ_5GHZ; + spur -= c->ic_freq; + if (abs(spur) < range) + break; + } + if (i == AR_EEPROM_MODAL_SPURS) + return; /* XXX disable if it was enabled! */ + DPRINTFN(2, ("enabling spur mitigation\n")); + + AR_SETBITS(sc, AR_PHY_TIMING_CTRL4_0, + AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | + AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | + AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | + AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); + + AR_WRITE(sc, AR_PHY_SPUR_REG, + AR_PHY_SPUR_REG_MASK_RATE_CNTL | + AR_PHY_SPUR_REG_ENABLE_MASK_PPM | + AR_PHY_SPUR_REG_MASK_RATE_SELECT | + AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | + SM(AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, AR_SPUR_RSSI_THRESH)); + + if (extc != NULL) { + spur_delta_phase = (spur * 262144) / 10; + if (spur < 0) { + spur_subchannel_sd = 1; + spur_off = spur + 10; + } else { + spur_subchannel_sd = 0; + spur_off = spur - 10; + } + } else { + spur_delta_phase = (spur * 524288) / 10; + spur_subchannel_sd = 0; + spur_off = spur; + } + if (IEEE80211_IS_CHAN_2GHZ(c)) + spur_freq_sd = (spur_off * 2048) / 44; + else + spur_freq_sd = (spur_off * 2048) / 40; + + AR_WRITE(sc, AR_PHY_TIMING11, + AR_PHY_TIMING11_USE_SPUR_IN_AGC | + SM(AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd) | + SM(AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase)); + + AR_WRITE(sc, AR_PHY_SFCORR_EXT, + SM(AR_PHY_SFCORR_SPUR_SUBCHNL_SD, spur_subchannel_sd)); + AR_WRITE_BARRIER(sc); + + bin = spur * 320; + ar5008_set_viterbi_mask(sc, bin); +} + +void +ar9280_reset_rx_gain(struct athn_softc *sc, struct ieee80211_channel *c) +{ + const struct athn_gain *prog = sc->rx_gain; + const uint32_t *pvals; + int i; + + if (IEEE80211_IS_CHAN_2GHZ(c)) + pvals = prog->vals_2g; + else + pvals = prog->vals_5g; + for (i = 0; i < prog->nregs; i++) + AR_WRITE(sc, prog->regs[i], pvals[i]); +} + +void +ar9280_reset_tx_gain(struct athn_softc *sc, struct ieee80211_channel *c) +{ + const struct athn_gain *prog = sc->tx_gain; + const uint32_t *pvals; + int i; + + if (IEEE80211_IS_CHAN_2GHZ(c)) + pvals = prog->vals_2g; + else + pvals = prog->vals_5g; + for (i = 0; i < prog->nregs; i++) + AR_WRITE(sc, prog->regs[i], pvals[i]); +} + +// Not needed +// void +// ar9280_olpc_init(struct athn_softc *sc) +// { +// uint32_t reg; +// int i; + +// /* Save original Tx gain values. */ +// for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++) { +// reg = AR_READ(sc, AR_PHY_TX_GAIN_TBL(i)); +// sc->tx_gain_tbl[i] = MS(reg, AR_PHY_TX_GAIN); +// } +// /* Initial Tx gain temperature compensation. */ +// sc->tcomp = 0; +// } + +// void +// ar9280_olpc_temp_compensation(struct athn_softc *sc) +// { +// const struct ar5416_eeprom *eep = sc->eep; +// int8_t pdadc, txgain, tcomp; +// uint32_t reg; +// int i; + +// reg = AR_READ(sc, AR_PHY_TX_PWRCTRL4); +// pdadc = MS(reg, AR_PHY_TX_PWRCTRL_PD_AVG_OUT); +// DPRINTFN(3, ("PD Avg Out=%d\n", pdadc)); + +// if (sc->pdadc == 0 || pdadc == 0) +// return; /* No frames transmitted yet. */ + +// /* Compute Tx gain temperature compensation. */ +// if (sc->eep_rev >= AR_EEP_MINOR_VER_20 && +// eep->baseEepHeader.dacHiPwrMode_5G) +// tcomp = (pdadc - sc->pdadc + 4) / 8; +// else +// tcomp = (pdadc - sc->pdadc + 5) / 10; +// DPRINTFN(3, ("OLPC temp compensation=%d\n", tcomp)); + +// if (tcomp == sc->tcomp) +// return; /* Don't rewrite the same values. */ +// sc->tcomp = tcomp; + +// /* Adjust Tx gain values. */ +// for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++) { +// txgain = sc->tx_gain_tbl[i] - tcomp; +// if (txgain < 0) +// txgain = 0; +// reg = AR_READ(sc, AR_PHY_TX_GAIN_TBL(i)); +// reg = RW(reg, AR_PHY_TX_GAIN, txgain); +// AR_WRITE(sc, AR_PHY_TX_GAIN_TBL(i), reg); +// } +// AR_WRITE_BARRIER(sc); +// } diff --git a/sys/dev/athn/ar9285.c b/sys/dev/athn/ar9285.c new file mode 100644 --- /dev/null +++ b/sys/dev/athn/ar9285.c @@ -0,0 +1,880 @@ +/* $OpenBSD: ar9285.c,v 1.30 2022/01/09 05:42:38 jsg Exp $ */ + +/*- + * Copyright (c) 2009-2010 Damien Bergamini + * Copyright (c) 2008-2010 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Driver for Atheros 802.11a/g/n chipsets. + * Routines for AR9285 and AR9271 chipsets. + */ + +// #include "athn_usb.h" +//#include "bpfilter.h" + +#include +#include +// #include +#include +#include +#include +#include +#include +//#include +#include +//#include +#include + +#include +//#include + +#if NBPFILTER > 0 +#include +#endif +#include +#include +#include +#include +#include + +#include +//#include +#include + + +#include +#include +#include +#include + +#include "athnreg.h" +#include "athnvar.h" + +#include "ar5008reg.h" +#include "ar9280reg.h" +#include "ar9285reg.h" + +int ar9285_attach(struct athn_softc *); +void ar9285_setup(struct athn_softc *); +void ar9285_swap_rom(struct athn_softc *); +const struct ar_spur_chan *ar9285_get_spur_chans(struct athn_softc *, int); +void ar9285_init_from_rom(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +void ar9285_pa_calib(struct athn_softc *); +void ar9271_pa_calib(struct athn_softc *); +int ar9285_cl_cal(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +void ar9271_load_ani(struct athn_softc *); +int ar9285_init_calib(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +void ar9285_get_pdadcs(struct athn_softc *, struct ieee80211_channel *, + int, uint8_t, uint8_t *, uint8_t *); +void ar9285_set_power_calib(struct athn_softc *, + struct ieee80211_channel *); +void ar9285_set_txpower(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); + +/* Extern functions. */ +uint8_t athn_chan2fbin(struct ieee80211_channel *); +void athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, int *); +int ar5008_attach(struct athn_softc *); +void ar5008_write_txpower(struct athn_softc *, int16_t power[]); +void ar5008_get_pdadcs(struct athn_softc *, uint8_t, struct athn_pier *, + struct athn_pier *, int, int, uint8_t, uint8_t *, uint8_t *); +void ar5008_get_lg_tpow(struct athn_softc *, struct ieee80211_channel *, + uint8_t, const struct ar_cal_target_power_leg *, int, uint8_t[]); +void ar5008_get_ht_tpow(struct athn_softc *, struct ieee80211_channel *, + uint8_t, const struct ar_cal_target_power_ht *, int, uint8_t[]); +int ar9280_set_synth(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +void ar9280_spur_mitigate(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); + + +int +ar9285_attach(struct athn_softc *sc) +{ + sc->eep_base = AR9285_EEP_START_LOC; + sc->eep_size = sizeof(struct ar9285_eeprom); + sc->ngpiopins = (sc->flags & ATHN_FLAG_USB) ? 16 : 12; + sc->led_pin = (sc->flags & ATHN_FLAG_USB) ? 15 : 1; + sc->workaround = AR9285_WA_DEFAULT; + sc->ops.setup = ar9285_setup; + sc->ops.swap_rom = ar9285_swap_rom; + sc->ops.init_from_rom = ar9285_init_from_rom; + sc->ops.set_txpower = ar9285_set_txpower; + sc->ops.set_synth = ar9280_set_synth; + sc->ops.spur_mitigate = ar9280_spur_mitigate; + sc->ops.get_spur_chans = ar9285_get_spur_chans; + + if (AR_SREV_9271(sc)) { + sc->cca_min_2g = AR9271_PHY_CCA_MIN_GOOD_VAL_2GHZ; + sc->cca_max_2g = AR9271_PHY_CCA_MAX_GOOD_VAL_2GHZ; + } else + { + sc->cca_min_2g = AR9285_PHY_CCA_MIN_GOOD_VAL_2GHZ; + sc->cca_max_2g = AR9285_PHY_CCA_MAX_GOOD_VAL_2GHZ; + } + if (AR_SREV_9271(sc)) + sc->ini = &ar9271_ini; + else + + sc->ini = &ar9285_1_2_ini; + sc->serdes = &ar9280_2_0_serdes; + + return (ar5008_attach(sc)); +} + +void +ar9285_setup(struct athn_softc *sc) +{ + const struct ar9285_eeprom *eep = sc->eep; + uint8_t type; + + /* Select initialization values based on ROM. */ + type = eep->baseEepHeader.txGainType; + DPRINTF(("Tx gain type=0x%x\n", type)); + + if (AR_SREV_9271(sc)) { + if (type == AR_EEP_TXGAIN_HIGH_POWER) + sc->tx_gain = &ar9271_tx_gain_high_power; + else + sc->tx_gain = &ar9271_tx_gain; + } else + if ((AR_READ(sc, AR_AN_SYNTH9) & 0x7) == 0x1) { /* XE rev. */ + if (type == AR_EEP_TXGAIN_HIGH_POWER) + sc->tx_gain = &ar9285_2_0_tx_gain_high_power; + else + sc->tx_gain = &ar9285_2_0_tx_gain; + } else { + if (type == AR_EEP_TXGAIN_HIGH_POWER) + sc->tx_gain = &ar9285_1_2_tx_gain_high_power; + else + sc->tx_gain = &ar9285_1_2_tx_gain; + } +} + +void +ar9285_swap_rom(struct athn_softc *sc) +{ + struct ar9285_eeprom *eep = sc->eep; + int i; + + eep->modalHeader.antCtrlCommon = + bswap32(eep->modalHeader.antCtrlCommon); + eep->modalHeader.antCtrlChain = + bswap32(eep->modalHeader.antCtrlChain); + + for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { + eep->modalHeader.spurChans[i].spurChan = + bswap16(eep->modalHeader.spurChans[i].spurChan); + } +} + +const struct ar_spur_chan * +ar9285_get_spur_chans(struct athn_softc *sc, int is2ghz) +{ + const struct ar9285_eeprom *eep = sc->eep; + + KASSERT(is2ghz, ("is2ghz")); + return (eep->modalHeader.spurChans); +} + +void +ar9285_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c, + struct ieee80211_channel *extc) +{ + const struct ar9285_eeprom *eep = sc->eep; + const struct ar9285_modal_eep_header *modal = &eep->modalHeader; + uint32_t reg, offset = 0x1000; + uint8_t ob[5], db1[5], db2[5]; + uint8_t txRxAtten; + + AR_WRITE(sc, AR_PHY_SWITCH_COM, modal->antCtrlCommon); + AR_WRITE(sc, AR_PHY_SWITCH_CHAIN_0, modal->antCtrlChain); + + reg = AR_READ(sc, AR_PHY_TIMING_CTRL4_0); + reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, modal->iqCalI); + reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, modal->iqCalQ); + AR_WRITE(sc, AR_PHY_TIMING_CTRL4_0, reg); + + if (sc->eep_rev >= AR_EEP_MINOR_VER_3) { + reg = AR_READ(sc, AR_PHY_GAIN_2GHZ); + reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, + modal->bswMargin); + reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_DB, + modal->bswAtten); + reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, + modal->xatten2Margin); + reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_DB, + modal->xatten2Db); + AR_WRITE(sc, AR_PHY_GAIN_2GHZ, reg); + + /* Duplicate values of chain 0 for chain 1. */ + reg = AR_READ(sc, AR_PHY_GAIN_2GHZ + offset); + reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, + modal->bswMargin); + reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_DB, + modal->bswAtten); + reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, + modal->xatten2Margin); + reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_DB, + modal->xatten2Db); + AR_WRITE(sc, AR_PHY_GAIN_2GHZ + offset, reg); + } + if (sc->eep_rev >= AR_EEP_MINOR_VER_3) + txRxAtten = modal->txRxAtten; + else /* Workaround for ROM versions < 14.3. */ + txRxAtten = 23; + reg = AR_READ(sc, AR_PHY_RXGAIN); + reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAtten); + reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_MARGIN, modal->rxTxMargin); + AR_WRITE(sc, AR_PHY_RXGAIN, reg); + + /* Duplicate values of chain 0 for chain 1. */ + reg = AR_READ(sc, AR_PHY_RXGAIN + offset); + reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAtten); + reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_MARGIN, modal->rxTxMargin); + AR_WRITE(sc, AR_PHY_RXGAIN + offset, reg); + + if (modal->version >= 3) { + /* Setup antenna diversity from ROM. */ + reg = AR_READ(sc, AR_PHY_MULTICHAIN_GAIN_CTL); + reg = RW(reg, AR9285_PHY_ANT_DIV_CTL_ALL, 0); + reg = RW(reg, AR9285_PHY_ANT_DIV_CTL, + (modal->ob_234 >> 12) & 0x1); + reg = RW(reg, AR9285_PHY_ANT_DIV_ALT_LNACONF, + (modal->db1_234 >> 12) & 0x3); + reg = RW(reg, AR9285_PHY_ANT_DIV_MAIN_LNACONF, + (modal->db1_234 >> 14) & 0x3); + reg = RW(reg, AR9285_PHY_ANT_DIV_ALT_GAINTB, + (modal->ob_234 >> 13) & 0x1); + reg = RW(reg, AR9285_PHY_ANT_DIV_MAIN_GAINTB, + (modal->ob_234 >> 14) & 0x1); + AR_WRITE(sc, AR_PHY_MULTICHAIN_GAIN_CTL, reg); + reg = AR_READ(sc, AR_PHY_MULTICHAIN_GAIN_CTL); /* Flush. */ + + reg = AR_READ(sc, AR_PHY_CCK_DETECT); + if (modal->ob_234 & (1 << 15)) + reg |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; + else + reg &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; + AR_WRITE(sc, AR_PHY_CCK_DETECT, reg); + reg = AR_READ(sc, AR_PHY_CCK_DETECT); /* Flush. */ + } + if (modal->version >= 2) { + ob [0] = (modal->ob_01 >> 0) & 0xf; + ob [1] = (modal->ob_01 >> 4) & 0xf; + ob [2] = (modal->ob_234 >> 0) & 0xf; + ob [3] = (modal->ob_234 >> 4) & 0xf; + ob [4] = (modal->ob_234 >> 8) & 0xf; + + db1[0] = (modal->db1_01 >> 0) & 0xf; + db1[1] = (modal->db1_01 >> 4) & 0xf; + db1[2] = (modal->db1_234 >> 0) & 0xf; + db1[3] = (modal->db1_234 >> 4) & 0xf; + db1[4] = (modal->db1_234 >> 8) & 0xf; + + db2[0] = (modal->db2_01 >> 0) & 0xf; + db2[1] = (modal->db2_01 >> 4) & 0xf; + db2[2] = (modal->db2_234 >> 0) & 0xf; + db2[3] = (modal->db2_234 >> 4) & 0xf; + db2[4] = (modal->db2_234 >> 8) & 0xf; + + } else if (modal->version == 1) { + ob [0] = (modal->ob_01 >> 0) & 0xf; + ob [1] = (modal->ob_01 >> 4) & 0xf; + /* Field ob_234 does not exist, use ob_01. */ + ob [2] = ob [3] = ob [4] = ob [1]; + + db1[0] = (modal->db1_01 >> 0) & 0xf; + db1[1] = (modal->db1_01 >> 4) & 0xf; + /* Field db1_234 does not exist, use db1_01. */ + db1[2] = db1[3] = db1[4] = db1[1]; + + db2[0] = (modal->db2_01 >> 0) & 0xf; + db2[1] = (modal->db2_01 >> 4) & 0xf; + /* Field db2_234 does not exist, use db2_01. */ + db2[2] = db2[3] = db2[4] = db2[1]; + + } else { + ob [0] = modal->ob_01; + ob [1] = ob [2] = ob [3] = ob [4] = ob [0]; + + db1[0] = modal->db1_01; + db1[1] = db1[2] = db1[3] = db1[4] = db1[0]; + + /* Field db2_01 does not exist, use db1_01. */ + db2[0] = modal->db1_01; + db2[1] = db2[2] = db2[3] = db2[4] = db2[0]; + } + if (AR_SREV_9271(sc)) { + reg = AR_READ(sc, AR9285_AN_RF2G3); + reg = RW(reg, AR9271_AN_RF2G3_OB_CCK, ob [0]); + reg = RW(reg, AR9271_AN_RF2G3_OB_PSK, ob [1]); + reg = RW(reg, AR9271_AN_RF2G3_OB_QAM, ob [2]); + reg = RW(reg, AR9271_AN_RF2G3_DB1, db1[0]); + AR_WRITE(sc, AR9285_AN_RF2G3, reg); + AR_WRITE_BARRIER(sc); + DELAY(100); + reg = AR_READ(sc, AR9285_AN_RF2G4); + reg = RW(reg, AR9271_AN_RF2G4_DB2, db2[0]); + AR_WRITE(sc, AR9285_AN_RF2G4, reg); + AR_WRITE_BARRIER(sc); + DELAY(100); + } else + { + reg = AR_READ(sc, AR9285_AN_RF2G3); + reg = RW(reg, AR9285_AN_RF2G3_OB_0, ob [0]); + reg = RW(reg, AR9285_AN_RF2G3_OB_1, ob [1]); + reg = RW(reg, AR9285_AN_RF2G3_OB_2, ob [2]); + reg = RW(reg, AR9285_AN_RF2G3_OB_3, ob [3]); + reg = RW(reg, AR9285_AN_RF2G3_OB_4, ob [4]); + reg = RW(reg, AR9285_AN_RF2G3_DB1_0, db1[0]); + reg = RW(reg, AR9285_AN_RF2G3_DB1_1, db1[1]); + reg = RW(reg, AR9285_AN_RF2G3_DB1_2, db1[2]); + AR_WRITE(sc, AR9285_AN_RF2G3, reg); + AR_WRITE_BARRIER(sc); + DELAY(100); + reg = AR_READ(sc, AR9285_AN_RF2G4); + reg = RW(reg, AR9285_AN_RF2G4_DB1_3, db1[3]); + reg = RW(reg, AR9285_AN_RF2G4_DB1_4, db1[4]); + reg = RW(reg, AR9285_AN_RF2G4_DB2_0, db2[0]); + reg = RW(reg, AR9285_AN_RF2G4_DB2_1, db2[1]); + reg = RW(reg, AR9285_AN_RF2G4_DB2_2, db2[2]); + reg = RW(reg, AR9285_AN_RF2G4_DB2_3, db2[3]); + reg = RW(reg, AR9285_AN_RF2G4_DB2_4, db2[4]); + AR_WRITE(sc, AR9285_AN_RF2G4, reg); + AR_WRITE_BARRIER(sc); + DELAY(100); + } + + reg = AR_READ(sc, AR_PHY_SETTLING); + reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->switchSettling); + AR_WRITE(sc, AR_PHY_SETTLING, reg); + + reg = AR_READ(sc, AR_PHY_DESIRED_SZ); + reg = RW(reg, AR_PHY_DESIRED_SZ_ADC, modal->adcDesiredSize); + AR_WRITE(sc, AR_PHY_DESIRED_SZ, reg); + + reg = SM(AR_PHY_RF_CTL4_TX_END_XPAA_OFF, modal->txEndToXpaOff); + reg |= SM(AR_PHY_RF_CTL4_TX_END_XPAB_OFF, modal->txEndToXpaOff); + reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAA_ON, modal->txFrameToXpaOn); + reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAB_ON, modal->txFrameToXpaOn); + AR_WRITE(sc, AR_PHY_RF_CTL4, reg); + + reg = AR_READ(sc, AR_PHY_RF_CTL3); + reg = RW(reg, AR_PHY_TX_END_TO_A2_RX_ON, modal->txEndToRxOn); + AR_WRITE(sc, AR_PHY_RF_CTL3, reg); + + reg = AR_READ(sc, AR_PHY_CCA(0)); + reg = RW(reg, AR9280_PHY_CCA_THRESH62, modal->thresh62); + AR_WRITE(sc, AR_PHY_CCA(0), reg); + + reg = AR_READ(sc, AR_PHY_EXT_CCA0); + reg = RW(reg, AR_PHY_EXT_CCA0_THRESH62, modal->thresh62); + AR_WRITE(sc, AR_PHY_EXT_CCA0, reg); + + if (sc->eep_rev >= AR_EEP_MINOR_VER_2) { + reg = AR_READ(sc, AR_PHY_RF_CTL2); + reg = RW(reg, AR_PHY_TX_END_PA_ON, + modal->txFrameToPaOn); + reg = RW(reg, AR_PHY_TX_END_DATA_START, + modal->txFrameToDataStart); + AR_WRITE(sc, AR_PHY_RF_CTL2, reg); + } + if (sc->eep_rev >= AR_EEP_MINOR_VER_3 && extc != NULL) { + reg = AR_READ(sc, AR_PHY_SETTLING); + reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->swSettleHt40); + AR_WRITE(sc, AR_PHY_SETTLING, reg); + } + AR_WRITE_BARRIER(sc); +} + +void +ar9285_pa_calib(struct athn_softc *sc) +{ + /* List of registers that need to be saved/restored. */ + static const uint16_t regs[] = { + AR9285_AN_TOP3, + AR9285_AN_RXTXBB1, + AR9285_AN_RF2G1, + AR9285_AN_RF2G2, + AR9285_AN_TOP2, + AR9285_AN_RF2G8, + AR9285_AN_RF2G7 + }; + uint32_t svg[7], reg, ccomp_svg; + int i; + + /* No PA calibration needed for high power solutions. */ + if (AR_SREV_9285(sc) && + ((struct ar9285_base_eep_header *)sc->eep)->txGainType == + AR_EEP_TXGAIN_HIGH_POWER) /* XXX AR9287? */ + return; + + /* Save registers. */ + for (i = 0; i < nitems(regs); i++) + svg[i] = AR_READ(sc, regs[i]); + + AR_CLRBITS(sc, AR9285_AN_RF2G6, 1); + AR_SETBITS(sc, AR_PHY(2), 1 << 27); + + AR_SETBITS(sc, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC); + AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1); + AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I); + AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF); + AR_CLRBITS(sc, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL); + AR_CLRBITS(sc, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB); + AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL); + /* Power down PA drivers. */ + AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1); + AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2); + AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT); + + reg = AR_READ(sc, AR9285_AN_RF2G8); + reg = RW(reg, AR9285_AN_RF2G8_PADRVGN2TAB0, 7); + AR_WRITE(sc, AR9285_AN_RF2G8, reg); + + reg = AR_READ(sc, AR9285_AN_RF2G7); + reg = RW(reg, AR9285_AN_RF2G7_PADRVGN2TAB0, 0); + AR_WRITE(sc, AR9285_AN_RF2G7, reg); + + reg = AR_READ(sc, AR9285_AN_RF2G6); + /* Save compensation capacitor value. */ + ccomp_svg = MS(reg, AR9285_AN_RF2G6_CCOMP); + /* Program compensation capacitor for dynamic PA. */ + reg = RW(reg, AR9285_AN_RF2G6_CCOMP, 0xf); + AR_WRITE(sc, AR9285_AN_RF2G6, reg); + + AR_WRITE(sc, AR9285_AN_TOP2, AR9285_AN_TOP2_DEFAULT); + AR_WRITE_BARRIER(sc); + DELAY(30); + + /* Clear offsets 6-1. */ + AR_CLRBITS(sc, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS_6_1); + /* Clear offset 0. */ + AR_CLRBITS(sc, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP); + /* Set offsets 6-1. */ + for (i = 6; i >= 1; i--) { + AR_SETBITS(sc, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS(i)); + AR_WRITE_BARRIER(sc); + DELAY(1); + if (AR_READ(sc, AR9285_AN_RF2G9) & AR9285_AN_RXTXBB1_SPARE9) { + AR_SETBITS(sc, AR9285_AN_RF2G6, + AR9285_AN_RF2G6_OFFS(i)); + } else { + AR_CLRBITS(sc, AR9285_AN_RF2G6, + AR9285_AN_RF2G6_OFFS(i)); + } + } + /* Set offset 0. */ + AR_SETBITS(sc, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP); + AR_WRITE_BARRIER(sc); + DELAY(1); + if (AR_READ(sc, AR9285_AN_RF2G9) & AR9285_AN_RXTXBB1_SPARE9) + AR_SETBITS(sc, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP); + else + AR_CLRBITS(sc, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP); + + AR_WRITE_BARRIER(sc); + + AR_SETBITS(sc, AR9285_AN_RF2G6, 1); + AR_CLRBITS(sc, AR_PHY(2), 1 << 27); + + /* Restore registers. */ + for (i = 0; i < nitems(regs); i++) + AR_WRITE(sc, regs[i], svg[i]); + + /* Restore compensation capacitor value. */ + reg = AR_READ(sc, AR9285_AN_RF2G6); + reg = RW(reg, AR9285_AN_RF2G6_CCOMP, ccomp_svg); + AR_WRITE(sc, AR9285_AN_RF2G6, reg); + AR_WRITE_BARRIER(sc); +} + +void +ar9271_pa_calib(struct athn_softc *sc) +{ + /* List of registers that need to be saved/restored. */ + static const uint16_t regs[] = { + AR9285_AN_TOP3, + AR9285_AN_RXTXBB1, + AR9285_AN_RF2G1, + AR9285_AN_RF2G2, + AR9285_AN_TOP2, + AR9285_AN_RF2G8, + AR9285_AN_RF2G7 + }; + uint32_t svg[7], reg, rf2g3_svg; + int i; + + /* Save registers. */ + for (i = 0; i < nitems(regs); i++) + svg[i] = AR_READ(sc, regs[i]); + + AR_CLRBITS(sc, AR9285_AN_RF2G6, 1); + AR_SETBITS(sc, AR_PHY(2), 1 << 27); + + AR_SETBITS(sc, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC); + AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1); + AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I); + AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF); + AR_CLRBITS(sc, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL); + AR_CLRBITS(sc, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB); + AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL); + /* Power down PA drivers. */ + AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1); + AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2); + AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT); + + reg = AR_READ(sc, AR9285_AN_RF2G8); + reg = RW(reg, AR9285_AN_RF2G8_PADRVGN2TAB0, 7); + AR_WRITE(sc, AR9285_AN_RF2G8, reg); + + reg = AR_READ(sc, AR9285_AN_RF2G7); + reg = RW(reg, AR9285_AN_RF2G7_PADRVGN2TAB0, 0); + AR_WRITE(sc, AR9285_AN_RF2G7, reg); + + /* Save compensation capacitor value. */ + reg = rf2g3_svg = AR_READ(sc, AR9285_AN_RF2G3); + /* Program compensation capacitor for dynamic PA. */ + reg = RW(reg, AR9271_AN_RF2G3_CCOMP, 0xfff); + AR_WRITE(sc, AR9285_AN_RF2G3, reg); + + AR_WRITE(sc, AR9285_AN_TOP2, AR9285_AN_TOP2_DEFAULT); + AR_WRITE_BARRIER(sc); + DELAY(30); + + /* Clear offsets 6-0. */ + AR_CLRBITS(sc, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS_6_0); + /* Set offsets 6-1. */ + for (i = 6; i >= 1; i--) { + reg = AR_READ(sc, AR9285_AN_RF2G6); + reg |= AR9271_AN_RF2G6_OFFS(i); + AR_WRITE(sc, AR9285_AN_RF2G6, reg); + AR_WRITE_BARRIER(sc); + DELAY(1); + if (!(AR_READ(sc, AR9285_AN_RF2G9) & AR9285_AN_RXTXBB1_SPARE9)) + reg &= ~AR9271_AN_RF2G6_OFFS(i); + AR_WRITE(sc, AR9285_AN_RF2G6, reg); + } + AR_WRITE_BARRIER(sc); + + AR_SETBITS(sc, AR9285_AN_RF2G6, 1); + AR_CLRBITS(sc, AR_PHY(2), 1 << 27); + + /* Restore registers. */ + for (i = 0; i < nitems(regs); i++) + AR_WRITE(sc, regs[i], svg[i]); + + /* Restore compensation capacitor value. */ + AR_WRITE(sc, AR9285_AN_RF2G3, rf2g3_svg); + AR_WRITE_BARRIER(sc); +} + +/* + * Carrier Leakage Calibration. + */ +int +ar9285_cl_cal(struct athn_softc *sc, struct ieee80211_channel *c, + struct ieee80211_channel *extc) +{ + int ntries; + + AR_SETBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); + if (0 && extc == NULL) { /* XXX IS_CHAN_HT20!! */ + AR_SETBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE); + AR_SETBITS(sc, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN); + AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, + AR_PHY_AGC_CONTROL_FLTR_CAL); + AR_CLRBITS(sc, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE); + AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); + for (ntries = 0; ntries < 10000; ntries++) { + if (!(AR_READ(sc, AR_PHY_AGC_CONTROL) & + AR_PHY_AGC_CONTROL_CAL)) + break; + DELAY(10); + } + if (ntries == 10000) + return (ETIMEDOUT); + AR_CLRBITS(sc, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN); + AR_CLRBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE); + AR_CLRBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); + } + AR_CLRBITS(sc, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); + AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); + AR_SETBITS(sc, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE); + AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); + for (ntries = 0; ntries < 10000; ntries++) { + if (!(AR_READ(sc, AR_PHY_AGC_CONTROL) & + AR_PHY_AGC_CONTROL_CAL)) + break; + DELAY(10); + } + if (ntries == 10000) + return (ETIMEDOUT); + AR_SETBITS(sc, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); + AR_CLRBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); + AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); + AR_WRITE_BARRIER(sc); + return (0); +} + +void +ar9271_load_ani(struct athn_softc *sc) +{ + /* Write ANI registers. */ + AR_WRITE(sc, AR_PHY_DESIRED_SZ, 0x6d4000e2); + AR_WRITE(sc, AR_PHY_AGC_CTL1, 0x3139605e); + AR_WRITE(sc, AR_PHY_FIND_SIG, 0x7ec84d2e); + AR_WRITE(sc, AR_PHY_SFCORR_LOW, 0x06903881); + AR_WRITE(sc, AR_PHY_SFCORR, 0x5ac640d0); + AR_WRITE(sc, AR_PHY_CCK_DETECT, 0x803e68c8); + AR_WRITE(sc, AR_PHY_TIMING5, 0xd00a8007); + AR_WRITE(sc, AR_PHY_SFCORR_EXT, 0x05eea6d4); + AR_WRITE_BARRIER(sc); +} + +int +ar9285_init_calib(struct athn_softc *sc, struct ieee80211_channel *c, + struct ieee80211_channel *extc) +{ + uint32_t reg, mask, clcgain, rf2g5_svg; + int i, maxgain, nclcs, thresh, error; + + /* Do carrier leakage calibration. */ + if ((error = ar9285_cl_cal(sc, c, extc)) != 0) + return (error); + + /* Workaround for high temperature is not applicable on AR9271. */ + if (AR_SREV_9271(sc)) + return (0); + + mask = 0; + nclcs = 0; + reg = AR_READ(sc, AR_PHY_TX_PWRCTRL7); + maxgain = MS(reg, AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX); + for (i = 0; i <= maxgain; i++) { + reg = AR_READ(sc, AR_PHY_TX_GAIN_TBL(i)); + clcgain = MS(reg, AR_PHY_TX_GAIN_CLC); + /* NB: clcgain <= 0xf. */ + if (!(mask & (1 << clcgain))) { + mask |= 1 << clcgain; + nclcs++; + } + } + thresh = 0; + for (i = 0; i < nclcs; i++) { + reg = AR_READ(sc, AR_PHY_CLC_TBL(i)); + if (MS(reg, AR_PHY_CLC_I0) == 0) + thresh++; + if (MS(reg, AR_PHY_CLC_Q0) == 0) + thresh++; + } + if (thresh <= AR9285_CL_CAL_REDO_THRESH) + return (0); /* No need to redo. */ + + /* Threshold reached, redo carrier leakage calibration. */ + DPRINTFN(2, ("CLC threshold=%d\n", thresh)); + rf2g5_svg = reg = AR_READ(sc, AR9285_AN_RF2G5); + if ((AR_READ(sc, AR_AN_SYNTH9) & 0x7) == 0x1) /* XE rev. */ + reg = RW(reg, AR9285_AN_RF2G5_IC50TX, 0x5); + else + reg = RW(reg, AR9285_AN_RF2G5_IC50TX, 0x4); + AR_WRITE(sc, AR9285_AN_RF2G5, reg); + AR_WRITE_BARRIER(sc); + error = ar9285_cl_cal(sc, c, extc); + AR_WRITE(sc, AR9285_AN_RF2G5, rf2g5_svg); + AR_WRITE_BARRIER(sc); + return (error); +} + +void +ar9285_get_pdadcs(struct athn_softc *sc, struct ieee80211_channel *c, + int nxpdgains, uint8_t overlap, uint8_t *boundaries, uint8_t *pdadcs) +{ + const struct ar9285_eeprom *eep = sc->eep; + const struct ar9285_cal_data_per_freq *pierdata; + const uint8_t *pierfreq; + struct athn_pier lopier, hipier; + uint8_t fbin; + int i, lo, hi, npiers; + + pierfreq = eep->calFreqPier2G; + pierdata = eep->calPierData2G; + npiers = AR9285_NUM_2G_CAL_PIERS; + + /* Find channel in ROM pier table. */ + fbin = athn_chan2fbin(c); + athn_get_pier_ival(fbin, pierfreq, npiers, &lo, &hi); + + lopier.fbin = pierfreq[lo]; + hipier.fbin = pierfreq[hi]; + for (i = 0; i < nxpdgains; i++) { + lopier.pwr[i] = pierdata[lo].pwrPdg[i]; + lopier.vpd[i] = pierdata[lo].vpdPdg[i]; + hipier.pwr[i] = pierdata[lo].pwrPdg[i]; + hipier.vpd[i] = pierdata[lo].vpdPdg[i]; + } + ar5008_get_pdadcs(sc, fbin, &lopier, &hipier, nxpdgains, + AR9285_PD_GAIN_ICEPTS, overlap, boundaries, pdadcs); +} + +void +ar9285_set_power_calib(struct athn_softc *sc, struct ieee80211_channel *c) +{ + const struct ar9285_eeprom *eep = sc->eep; + uint8_t boundaries[AR_PD_GAINS_IN_MASK]; + uint8_t pdadcs[AR_NUM_PDADC_VALUES]; + uint8_t xpdgains[AR9285_NUM_PD_GAINS]; + uint8_t overlap; + uint32_t reg; + int i, nxpdgains; + + if (sc->eep_rev < AR_EEP_MINOR_VER_2) { + overlap = MS(AR_READ(sc, AR_PHY_TPCRG5), + AR_PHY_TPCRG5_PD_GAIN_OVERLAP); + } else + overlap = eep->modalHeader.pdGainOverlap; + + nxpdgains = 0; + memset(xpdgains, 0, sizeof(xpdgains)); + for (i = AR9285_PD_GAINS_IN_MASK - 1; i >= 0; i--) { + if (nxpdgains >= AR9285_NUM_PD_GAINS) + break; + if (eep->modalHeader.xpdGain & (1 << i)) + xpdgains[nxpdgains++] = i; + } + reg = AR_READ(sc, AR_PHY_TPCRG1); + reg = RW(reg, AR_PHY_TPCRG1_NUM_PD_GAIN, nxpdgains - 1); + reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_1, xpdgains[0]); + reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_2, xpdgains[1]); + AR_WRITE(sc, AR_PHY_TPCRG1, reg); + + /* NB: No open loop power control for AR9285. */ + ar9285_get_pdadcs(sc, c, nxpdgains, overlap, boundaries, pdadcs); + + /* Write boundaries. */ + reg = SM(AR_PHY_TPCRG5_PD_GAIN_OVERLAP, overlap); + reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1, boundaries[0]); + reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2, boundaries[1]); + reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3, boundaries[2]); + reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4, boundaries[3]); + AR_WRITE(sc, AR_PHY_TPCRG5, reg); + + /* Write PDADC values. */ + for (i = 0; i < AR_NUM_PDADC_VALUES; i += 4) { + AR_WRITE(sc, AR_PHY_PDADC_TBL_BASE + i, + pdadcs[i + 0] << 0 | + pdadcs[i + 1] << 8 | + pdadcs[i + 2] << 16 | + pdadcs[i + 3] << 24); + } + AR_WRITE_BARRIER(sc); +} + +void +ar9285_set_txpower(struct athn_softc *sc, struct ieee80211_channel *c, + struct ieee80211_channel *extc) +{ + const struct ar9285_eeprom *eep = sc->eep; + const struct ar9285_modal_eep_header *modal = &eep->modalHeader; + uint8_t tpow_cck[4], tpow_ofdm[4]; + uint8_t tpow_cck_ext[4], tpow_ofdm_ext[4]; + uint8_t tpow_ht20[8], tpow_ht40[8]; + uint8_t ht40inc; + int16_t max_ant_gain, power[ATHN_POWER_COUNT]; + int i; + + ar9285_set_power_calib(sc, c); + + /* Compute transmit power reduction due to antenna gain. */ + max_ant_gain = modal->antennaGain; + /* XXX */ + + /* Get CCK target powers. */ + ar5008_get_lg_tpow(sc, c, AR_CTL_11B, eep->calTargetPowerCck, + AR9285_NUM_2G_CCK_TARGET_POWERS, tpow_cck); + + /* Get OFDM target powers. */ + ar5008_get_lg_tpow(sc, c, AR_CTL_11G, eep->calTargetPower2G, + AR9285_NUM_2G_20_TARGET_POWERS, tpow_ofdm); + + /* Get HT-20 target powers. */ + ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT20, eep->calTargetPower2GHT20, + AR9285_NUM_2G_20_TARGET_POWERS, tpow_ht20); + + if (extc != NULL) { + /* Get HT-40 target powers. */ + ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT40, + eep->calTargetPower2GHT40, AR9285_NUM_2G_40_TARGET_POWERS, + tpow_ht40); + + /* Get secondary channel CCK target powers. */ + ar5008_get_lg_tpow(sc, extc, AR_CTL_11B, + eep->calTargetPowerCck, AR9285_NUM_2G_CCK_TARGET_POWERS, + tpow_cck_ext); + + /* Get secondary channel OFDM target powers. */ + ar5008_get_lg_tpow(sc, extc, AR_CTL_11G, + eep->calTargetPower2G, AR9285_NUM_2G_20_TARGET_POWERS, + tpow_ofdm_ext); + } + + memset(power, 0, sizeof(power)); + /* Shuffle target powers across transmit rates. */ + power[ATHN_POWER_OFDM6 ] = + power[ATHN_POWER_OFDM9 ] = + power[ATHN_POWER_OFDM12 ] = + power[ATHN_POWER_OFDM18 ] = + power[ATHN_POWER_OFDM24 ] = tpow_ofdm[0]; + power[ATHN_POWER_OFDM36 ] = tpow_ofdm[1]; + power[ATHN_POWER_OFDM48 ] = tpow_ofdm[2]; + power[ATHN_POWER_OFDM54 ] = tpow_ofdm[3]; + power[ATHN_POWER_XR ] = tpow_ofdm[0]; + power[ATHN_POWER_CCK1_LP ] = tpow_cck[0]; + power[ATHN_POWER_CCK2_LP ] = + power[ATHN_POWER_CCK2_SP ] = tpow_cck[1]; + power[ATHN_POWER_CCK55_LP] = + power[ATHN_POWER_CCK55_SP] = tpow_cck[2]; + power[ATHN_POWER_CCK11_LP] = + power[ATHN_POWER_CCK11_SP] = tpow_cck[3]; + for (i = 0; i < nitems(tpow_ht20); i++) + power[ATHN_POWER_HT20(i)] = tpow_ht20[i]; + if (extc != NULL) { + /* Correct PAR difference between HT40 and HT20/Legacy. */ + if (sc->eep_rev >= AR_EEP_MINOR_VER_2) + ht40inc = modal->ht40PowerIncForPdadc; + else + ht40inc = AR_HT40_POWER_INC_FOR_PDADC; + for (i = 0; i < nitems(tpow_ht40); i++) + power[ATHN_POWER_HT40(i)] = tpow_ht40[i] + ht40inc; + power[ATHN_POWER_OFDM_DUP] = tpow_ht40[0]; + power[ATHN_POWER_CCK_DUP ] = tpow_ht40[0]; + power[ATHN_POWER_OFDM_EXT] = tpow_ofdm_ext[0]; + power[ATHN_POWER_CCK_EXT ] = tpow_cck_ext[0]; + } + + for (i = 0; i < ATHN_POWER_COUNT; i++) { + power[i] -= AR_PWR_TABLE_OFFSET_DB * 2; /* In half dB. */ + if (power[i] > AR_MAX_RATE_POWER) + power[i] = AR_MAX_RATE_POWER; + } + + /* Commit transmit power values to hardware. */ + ar5008_write_txpower(sc, power); +} diff --git a/sys/dev/athn/athn.c b/sys/dev/athn/athn.c new file mode 100644 --- /dev/null +++ b/sys/dev/athn/athn.c @@ -0,0 +1,3549 @@ +/* $OpenBSD: athn.c,v 1.111 2021/04/15 18:25:43 stsp Exp $ */ + +/*- + * Copyright (c) 2009 Damien Bergamini + * Copyright (c) 2008-2010 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Driver for Atheros 802.11a/g/n chipsets. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* uintptr_t */ +#include +#include + +// #if NBPFILTER > 0 +// #include +// #endif +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "athnreg.h" +#include "athnvar.h" +#include "openbsd_adapt.h" + +// TODO missing macro def +#define NATHN_USB 1 + +#ifdef ATHN_DEBUG +int athn_debug = 0; +#endif + +void athn_radiotap_attach(struct athn_softc *); +void athn_get_chanlist(struct athn_softc *); +const char * athn_get_mac_name(struct athn_softc *); +const char * athn_get_rf_name(struct athn_softc *); +void athn_led_init(struct athn_softc *); +void athn_set_led(struct athn_softc *, int); +void athn_btcoex_init(struct athn_softc *); +void athn_btcoex_enable(struct athn_softc *); +void athn_btcoex_disable(struct athn_softc *); +void athn_set_rxfilter(struct athn_softc *, uint32_t); +void athn_get_chipid(struct athn_softc *); +int athn_reset_power_on(struct athn_softc *); +int athn_reset(struct athn_softc *, int); +void athn_init_pll(struct athn_softc *, + const struct ieee80211_channel *); +int athn_set_power_awake(struct athn_softc *); +void athn_set_power_sleep(struct athn_softc *); +void athn_write_serdes(struct athn_softc *, + const struct athn_serdes *); +void athn_config_pcie(struct athn_softc *); +void athn_config_nonpcie(struct athn_softc *); +int athn_set_chan(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +int athn_switch_chan(struct athn_softc *, + struct ieee80211_channel *, struct ieee80211_channel *); +void athn_get_delta_slope(uint32_t, uint32_t *, uint32_t *); +void athn_reset_key(struct athn_softc *, int); +int athn_set_key(struct ieee80211com *, struct ieee80211_node *, + struct ieee80211_key *); +void athn_delete_key(struct ieee80211com *, struct ieee80211_node *, + struct ieee80211_key *); +void athn_iter_calib(void *, struct ieee80211_node *); +int athn_cap_noisefloor(struct athn_softc *, int); +int athn_nf_hist_mid(int *, int); +void athn_filter_noisefloor(struct athn_softc *); +void athn_start_noisefloor_calib(struct athn_softc *, int); +void athn_calib_to(void *); +int athn_init_calib(struct athn_softc *, + struct ieee80211_channel *, struct ieee80211_channel *); +uint8_t athn_chan2fbin(struct ieee80211_channel *); +int athn_interpolate(int, int, int, int, int); +void athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, + int *); +void athn_init_dma(struct athn_softc *); +void athn_rx_start(struct athn_softc *); +void athn_inc_tx_trigger_level(struct athn_softc *); +int athn_stop_rx_dma(struct athn_softc *); +int athn_rx_abort(struct athn_softc *); +void athn_tx_reclaim(struct athn_softc *, int); +int athn_tx_pending(struct athn_softc *, int); +void athn_stop_tx_dma(struct athn_softc *, int); +int athn_txtime(struct athn_softc *, int, int, u_int); +void athn_set_sta_timers(struct athn_softc *); +void athn_set_hostap_timers(struct athn_softc *); +void athn_set_opmode(struct athn_softc *); +void athn_set_bss(struct athn_softc *, struct ieee80211_node *); +void athn_enable_interrupts(struct athn_softc *); +void athn_disable_interrupts(struct athn_softc *); +void athn_init_qos(struct athn_softc *); +int athn_hw_reset(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *, int); +struct ieee80211_node *athn_node_alloc(struct ieee80211com *); +void athn_newassoc(struct ieee80211com *, struct ieee80211_node *, + int); +int athn_media_change(struct ifnet *); +void athn_next_scan(void *); +int athn_newstate(struct ieee80211com *, enum ieee80211_state, + int); +void athn_updateedca(struct ieee80211com *); +int athn_clock_rate(struct athn_softc *); +int athn_chan_sifs(struct ieee80211_channel *); +void athn_setsifs(struct athn_softc *); +int athn_acktimeout(struct ieee80211_channel *, int); +void athn_setacktimeout(struct athn_softc *, + struct ieee80211_channel *, int); +void athn_setctstimeout(struct athn_softc *, + struct ieee80211_channel *, int); +void athn_setclockrate(struct athn_softc *); +void athn_updateslot(struct ieee80211com *); +void athn_start(struct ifnet *); +void athn_watchdog(struct ifnet *); +void athn_set_multi(struct athn_softc *); +int athn_ioctl(struct ifnet *, u_long, caddr_t); +int athn_init(struct ifnet *); +void athn_stop(struct ifnet *, int); +void athn_init_tx_queues(struct athn_softc *); +int32_t athn_ani_get_rssi(struct athn_softc *); +void athn_ani_ofdm_err_trigger(struct athn_softc *); +void athn_ani_cck_err_trigger(struct athn_softc *); +void athn_ani_lower_immunity(struct athn_softc *); +void athn_ani_restart(struct athn_softc *); +void athn_ani_monitor(struct athn_softc *); + +/* Extern functions. */ +int ar9285_attach(struct athn_softc *); +int ar9285_init_calib(struct athn_softc *, + struct ieee80211_channel *, struct ieee80211_channel *); +void ar9271_pa_calib(struct athn_softc *); + + +// TODO missing in sys/device.h +/* + * Minimal device structures. + * Note that all ``system'' device types are listed here. + */ +// enum devclass { +// DV_DULL, /* generic, no special info */ +// DV_CPU, /* CPU (carries resource utilization) */ +// DV_DISK, /* disk drive (label, etc) */ +// DV_IFNET, /* network interface */ +// DV_TAPE, /* tape device */ +// DV_TTY /* serial line interface (???) */ +// }; + +#if 0 +struct cfdriver athn_cd = { + NULL, "athn", DV_IFNET +}; +#endif + + +// TODO missing in net80211/ieee80211.h +#define IEEE80211_HTCAP_SMPS_DIS 3 +#define IEEE80211_HTCAP_SMPS_SHIFT 2 + +static void +athn_config_ht(struct athn_softc *sc) +{ + __attribute__((unused)) struct ieee80211com *ic = &sc->sc_ic; + int ntxstreams, nrxstreams; + + if ((sc->flags & ATHN_FLAG_11N) == 0) + return; + + /* Set HT capabilities. */ + // ic->ic_htcaps = (IEEE80211_HTCAP_SMPS_DIS << + // IEEE80211_HTCAP_SMPS_SHIFT); +#ifdef notyet + ic->ic_htcaps |= IEEE80211_HTCAP_CBW20_40 | + IEEE80211_HTCAP_SGI40 | + IEEE80211_HTCAP_DSSSCCK40; +#endif + // TODO missing field + // ic->ic_htxcaps = 0; +#ifdef notyet + if (AR_SREV_9271(sc) || AR_SREV_9287_10_OR_LATER(sc)) + ic->ic_htcaps |= IEEE80211_HTCAP_SGI20; + if (AR_SREV_9380_10_OR_LATER(sc)) + ic->ic_htcaps |= IEEE80211_HTCAP_LDPC; + if (AR_SREV_9280_10_OR_LATER(sc)) { + ic->ic_htcaps |= IEEE80211_HTCAP_TXSTBC; + ic->ic_htcaps |= 1 << IEEE80211_HTCAP_RXSTBC_SHIFT; + } +#endif + ntxstreams = sc->ntxchains; + nrxstreams = sc->nrxchains; + if (!AR_SREV_9380_10_OR_LATER(sc)) { + ntxstreams = MIN(ntxstreams, 2); + nrxstreams = MIN(nrxstreams, 2); + } + // TODO missing fields + /* Set supported HT rates. */ + // if (ic->ic_userflags & IEEE80211_F_NOMIMO) + // ntxstreams = nrxstreams = 1; + // memset(ic->ic_sup_mcs, 0, sizeof(ic->ic_sup_mcs)); + // for (i = 0; i < nrxstreams; i++) + // ic->ic_sup_mcs[i] = 0xff; + // ic->ic_tx_mcs_set = IEEE80211_TX_MCS_SET_DEFINED; + // if (ntxstreams != nrxstreams) { + // ic->ic_tx_mcs_set |= IEEE80211_TX_RX_MCS_NOT_EQUAL; + // ic->ic_tx_mcs_set |= (ntxstreams - 1) << 2; + // } +} +// TODO: Move to header +#ifndef AR5416_OPFLAGS_11G +#define AR5416_OPFLAGS_11A 0x01 +#define AR5416_OPFLAGS_11G 0x02 +#endif + +// Naming convention from otus. +// Function similar to athn_get_chanlist but with other parametrs so it can be used as a callback +static void +athn_getradiocaps(struct ieee80211com *ic, + int maxchans, int *nchans, struct ieee80211_channel chans[]) +{ + struct athn_softc *sc = ic->ic_softc; + uint8_t bands[IEEE80211_MODE_BYTES]; + int cbw_flags; + + memset(bands, 0, sizeof(bands)); + + + cbw_flags = (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) ? + NET80211_CBW_FLAG_HT40 : 0; + /* Set supported rates. */ + + // printf("ATHN_FLAG_11G"); + setbit(bands, IEEE80211_MODE_11B); + setbit(bands, IEEE80211_MODE_11G); + setbit(bands, IEEE80211_MODE_11NG); + ieee80211_add_channels_default_2ghz(chans, maxchans, nchans, + bands, cbw_flags); + if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) { + printf("ATHN_FLAG_11A"); + setbit(bands, IEEE80211_MODE_11A); + setbit(bands, IEEE80211_MODE_11NA); + ieee80211_add_channel_list_5ghz(ic->ic_channels, IEEE80211_CHAN_MAX, nchans, + athn_5ghz_chans, nitems(athn_5ghz_chans), bands, 0); + } +} + +// TODO: check if we can go back to athn_attach +#if 0 +int +athn_attach(struct athn_softc *sc) +{ + __attribute__((unused)) struct ieee80211com *ic = &sc->sc_ic; + // TODO missing field ic_if' in 'struct ieee80211com' + // struct ifnet *ifp = &ic->ic_if; + struct ifnet *ifp = NULL; + int error; + + /* Read hardware revision. */ + athn_get_chipid(sc); + + device_printf(sc->sc_dev, "%s: chip id read\n", __func__); + + if ((error = athn_reset_power_on(sc)) != 0) { + device_printf(sc->sc_dev, "%s: could not reset chip\n", __func__); + return (error); + } + + if ((error = athn_set_power_awake(sc)) != 0) { + device_printf(sc->sc_dev, "%s: could not wakeup chip\n", __func__); + return (error); + } + +#if OpenBSD_IEEE80211_API + if (AR_SREV_9271(sc)) + error = ar9285_attach(sc); + + else + error = ENOTSUP; +#endif + + if (error != 0) { + // TOTO missing field 'dv_xname' in 'struct device' + // printf("%s: could not attach chip\n", sc->sc_dev.dv_xname); + return (error); + } + + /* We can put the chip in sleep state now. */ + athn_set_power_sleep(sc); + + if (!(sc->flags & ATHN_FLAG_USB)) { + error = sc->ops.dma_alloc(sc); + if (error != 0) { + // TOTO missing field 'dv_xname' in 'struct device' + // printf("%s: could not allocate DMA resources\n", + // sc->sc_dev.dv_xname); + return (error); + } + /* Steal one Tx buffer for beacons. */ + sc->bcnbuf = SIMPLEQ_FIRST(&sc->txbufs); + SIMPLEQ_REMOVE_HEAD(&sc->txbufs, bf_list); + } + + if (sc->flags & ATHN_FLAG_RFSILENT) { + DPRINTF(("found RF switch connected to GPIO pin %d\n", + sc->rfsilent_pin)); + } + DPRINTF(("%d key cache entries\n", sc->kc_entries)); + + /* + * In HostAP mode, the number of STAs that we can handle is + * limited by the number of entries in the HW key cache. + * TKIP keys would consume 2 entries in this cache but we + * only use the hardware crypto engine for CCMP. + */ + // TODO missing field 'ic_max_nnodes' in 'struct ieee80211com' + // ic->ic_max_nnodes = sc->kc_entries - IEEE80211_WEP_NKID; + // if (ic->ic_max_nnodes > IEEE80211_CACHE_SIZE) + // ic->ic_max_nnodes = IEEE80211_CACHE_SIZE; + + DPRINTF(("using %s loop power control\n", + (sc->flags & ATHN_FLAG_OLPC) ? "open" : "closed")); + + DPRINTF(("txchainmask=0x%x rxchainmask=0x%x\n", + sc->txchainmask, sc->rxchainmask)); + /* Count the number of bits set (in lowest 3 bits). */ + sc->ntxchains = + ((sc->txchainmask >> 2) & 1) + + ((sc->txchainmask >> 1) & 1) + + ((sc->txchainmask >> 0) & 1); + sc->nrxchains = + ((sc->rxchainmask >> 2) & 1) + + ((sc->rxchainmask >> 1) & 1) + + ((sc->rxchainmask >> 0) & 1); + + if (AR_SINGLE_CHIP(sc)) { + // TOTO missing field 'dv_xname' in 'struct device' + // printf("%s: %s rev %d (%dT%dR), ROM rev %d, address %s\n", + // sc->sc_dev.dv_xname, athn_get_mac_name(sc), sc->mac_rev, + // sc->ntxchains, sc->nrxchains, sc->eep_rev, + // ether_sprintf(ic->ic_myaddr)); + } else { + // TOTO missing field 'dv_xname' in 'struct device' + // printf("%s: MAC %s rev %d, RF %s (%dT%dR), ROM rev %d, " + // "address %s\n", + // sc->sc_dev.dv_xname, athn_get_mac_name(sc), sc->mac_rev, + // athn_get_rf_name(sc), sc->ntxchains, sc->nrxchains, + // sc->eep_rev, ether_sprintf(ic->ic_myaddr)); + } +#if OpenBSD_IEEE80211_API + // TODO: port everything below +#else + device_printf(sc->sc_dev, "%s: Planned return on line: %d\n", __func__, __LINE__); + return 0; +#endif + + +#if OpenBSD_ONLY + timeout_set(&sc->scan_to, athn_next_scan, sc); + timeout_set(&sc->calib_to, athn_calib_to, sc); +#endif + sc->amrr.amrr_min_success_threshold = 1; + sc->amrr.amrr_max_success_threshold = 15; + + ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ + ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ + // TODO missing field 'ic_state' in 'struct ieee80211com' + // ic->ic_state = IEEE80211_S_INIT; + + // TODO missing macros in ieee80211_var.h + /* ic_caps */ +#define IEEE80211_C_WEP 0x00000001 /* CAPABILITY: WEP available */ +#define IEEE80211_C_APPMGT 0x00000020 /* CAPABILITY: AP power mgmt */ +#define IEEE80211_C_SCANALL 0x00000400 /* CAPABILITY: scan all chan */ +#define IEEE80211_C_QOS 0x00000800 /* CAPABILITY: QoS avail */ +#define IEEE80211_C_RSN 0x00001000 /* CAPABILITY: RSN avail */ +#define IEEE80211_C_MFP 0x00002000 /* CAPABILITY: MFP avail */ +#define IEEE80211_C_RAWCTL 0x00004000 /* CAPABILITY: raw ctl */ +#define IEEE80211_C_SCANALLBAND 0x00008000 /* CAPABILITY: scan all bands */ +#define IEEE80211_C_TX_AMPDU 0x00010000 /* CAPABILITY: send A-MPDU */ +#define IEEE80211_C_ADDBA_OFFLOAD 0x00020000 /* CAPABILITY: ADDBA offload */ + + + + /* Set device capabilities. */ + ic->ic_caps = + IEEE80211_C_WEP | /* WEP. */ + IEEE80211_C_RSN | /* WPA/RSN. */ +#ifndef IEEE80211_STA_ONLY + IEEE80211_C_HOSTAP | /* Host AP mode supported. */ + IEEE80211_C_APPMGT | /* Host AP power saving supported. */ +#endif + IEEE80211_C_MONITOR | /* Monitor mode supported. */ + IEEE80211_C_SHSLOT | /* Short slot time supported. */ + IEEE80211_C_SHPREAMBLE | /* Short preamble supported. */ + IEEE80211_C_PMGT; /* Power saving supported. */ + + athn_config_ht(sc); + + /* Get the list of authorized/supported channels. */ + /* TODO: Is this function needed when athn_getradiocaps is available? */ + athn_get_chanlist(sc); + + athn_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans, ic->ic_channels); + + /* IBSS channel undefined for now. */ + // TODO missing 'ic_ibss_chan' in 'struct ieee80211com' + // ic->ic_ibss_chan = &ic->ic_channels[0]; +#if OpenBSD_IEEE80211_API + ifp->if_softc = sc; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = athn_ioctl; + ifp->if_start = athn_start; +#endif + // TODO + // ifp->if_watchdog = athn_watchdog; + // TOTO missing field 'dv_xname' in 'struct device' + // memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); + + // TODO missing members in 'struct ieee80211com' + // if_attach(ifp); + // ieee80211_ifattach(ifp); + // ic->ic_node_alloc = athn_node_alloc; + // ic->ic_newassoc = athn_newassoc; + ic->ic_updateslot = athn_updateslot; + ic->ic_getradiocaps = athn_getradiocaps; + // ic->ic_updateedca = athn_updateedca; + // ic->ic_set_key = athn_set_key; + // ic->ic_delete_key = athn_delete_key; + + /* Override 802.11 state transition machine. */ + // sc->sc_newstate = ic->ic_newstate; + // ic->ic_newstate = athn_newstate; + // ieee80211_media_init(ifp, athn_media_change, ieee80211_media_status); + +#if NBPFILTER > 0 + athn_radiotap_attach(sc); +#endif + + return (0); +} +#else +extern int athn_usb_read_rom(struct athn_softc *); + +static void +athn_scan_start(struct ieee80211com *ic) +{ + +// printf("%s: TODO\n", __func__); +} + +static void +athn_scan_end(struct ieee80211com *ic) +{ + +// printf("%s: TODO\n", __func__); +} + +// Implemented in athn_usb +// static int +// athn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, +// const struct ieee80211_bpf_params *params) +// { +// // struct ieee80211com *ic= ni->ni_ic; +// // struct athn_softc *sc = ic->ic_softc; +// // struct otus_data *bf = NULL; +// // int error = 0; + +// // /* Don't transmit if we're not running */ +// // // OTUS_LOCK(sc); +// // // if (! sc->sc_running) { +// // // error = ENETDOWN; +// // // goto error; +// // // } + +// // bf = otus_getbuf(sc); +// // if (bf == NULL) { +// // error = ENOBUFS; +// // goto error; +// // } + +// // if (otus_tx(sc, ni, m, bf, params) != 0) { +// // error = EIO; +// // goto error; +// // } + +// // OTUS_UNLOCK(sc); +// // return (0); +// // error: +// // if (bf) +// // otus_freebuf(sc, bf); +// // OTUS_UNLOCK(sc); +// // m_freem(m); +// // return (error); +// return 0; +// } + +static void +athn_parent(struct ieee80211com *ic) +{ + struct otus_softc *sc = ic->ic_softc; + // int startall = 0; + ieee80211_start_all(ic); +} + +int +athn_like_otus_attach(struct athn_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + uint32_t in, out; + uint8_t bands[IEEE80211_MODE_BYTES]; + int error; + + /* Read hardware revision. */ + athn_get_chipid(sc); + + ATHN_LOCK(sc); + + error = ar9285_attach(sc); + + + sc->eep_base = AR9285_EEP_START_LOC; + sc->eep_size = sizeof(struct ar9285_eeprom); + + if (error != 0) { + device_printf(sc->sc_dev, "%s: could not attach chip\n", __func__); + return (error); + } + + // TASK_INIT(&sc->tx_task, 0, otus_tx_task, sc); + + sc->eep = &sc->eeprom; + /* Read entire EEPROM. */ + if (athn_usb_read_rom(sc) != 0) { + ATHN_UNLOCK(sc); + device_printf(sc->sc_dev, + "%s: could not read EEPROM\n", + __func__); + return (ENXIO); + } + + ATHN_UNLOCK(sc); + + uint8_t txmask = sc->eeprom.baseEepHeader.txMask; + uint8_t rxmask = sc->eeprom.baseEepHeader.rxMask; + uint8_t capflags = sc->eeprom.baseEepHeader.opCapFlags; + + device_printf(sc->sc_dev, + "%s ic_macaddr = %s", + __func__, ether_sprintf(ic->ic_macaddr)); + + IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->eeprom.baseEepHeader.macAddr); + + if (txmask == 0x5) + ic->ic_txstream = 2; + else + ic->ic_txstream = 1; + + if (rxmask == 0x5) + ic->ic_rxstream = 2; + else + ic->ic_rxstream = 1; + +#define AR5416_OPFLAGS_11A 0x01 + + device_printf(sc->sc_dev,"%s: rx streams = %u, tx streams = %u\n", __func__, ic->ic_rxstream, ic->ic_txstream); + + device_printf(sc->sc_dev, + "MAC/BBP AR9271, RF AR%X, MIMO %dT%dR, address %s\n", + (capflags & AR5416_OPFLAGS_11A) ? + 0x9104 : ((txmask == 0x5) ? 0x9102 : 0x9101), + (txmask == 0x5) ? 2 : 1, (rxmask == 0x5) ? 2 : 1, + ether_sprintf(ic->ic_macaddr)); + + ic->ic_softc = sc; + ic->ic_name = device_get_nameunit(sc->sc_dev); + ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ + ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ + + /* Set device capabilities. */ + ic->ic_caps = + IEEE80211_C_STA | /* station mode */ +#if 0 + IEEE80211_C_BGSCAN | /* Background scan. */ +#endif + IEEE80211_C_SHPREAMBLE | /* Short preamble supported. */ + IEEE80211_C_WME | /* WME/QoS */ + IEEE80211_C_SHSLOT | /* Short slot time supported. */ + IEEE80211_C_FF | /* Atheros fast-frames supported. */ + IEEE80211_C_MONITOR | /* Enable monitor mode */ + IEEE80211_C_SWAMSDUTX | /* Do software A-MSDU TX */ + IEEE80211_C_WPA; /* WPA/RSN. */ + + ic->ic_htcaps = + IEEE80211_HTC_HT | +#if 0 + IEEE80211_HTC_AMPDU | +#endif + IEEE80211_HTC_AMSDU | + IEEE80211_HTCAP_MAXAMSDU_3839 | + IEEE80211_HTCAP_SMPS_OFF; + + athn_get_chanlist(sc); + + sc->flags |= ATHN_FLAG_11G; + + + athn_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans, + ic->ic_channels); + + memset(bands, 0, sizeof(bands)); + setbit(bands, IEEE80211_MODE_11B); + setbit(bands, IEEE80211_MODE_11G); + + ieee80211_init_channels(ic, NULL, bands); + + ieee80211_ifattach(ic); + // ic->ic_raw_xmit = athn_raw_xmit; + ic->ic_scan_start = athn_scan_start; + ic->ic_scan_end = athn_scan_end; + ic->ic_parent = athn_parent; +// TODO: add missing functions to ic +#if 0 + ic->ic_raw_xmit = otus_raw_xmit; + ic->ic_scan_start = otus_scan_start; + ic->ic_scan_end = otus_scan_end; + ic->ic_set_channel = otus_set_channel; +#endif + ic->ic_getradiocaps = athn_getradiocaps; +#if 0 + ic->ic_vap_create = otus_vap_create; + ic->ic_vap_delete = otus_vap_delete; + ic->ic_update_mcast = otus_update_mcast; + ic->ic_update_promisc = otus_update_mcast; + ic->ic_parent = otus_parent; + ic->ic_transmit = otus_transmit; + ic->ic_update_chw = otus_update_chw; + ic->ic_ampdu_enable = otus_ampdu_enable; + ic->ic_wme.wme_update = otus_updateedca; + ic->ic_newassoc = otus_newassoc; + ic->ic_node_alloc = otus_node_alloc; + + +#ifdef notyet + ic->ic_set_key = otus_set_key; + ic->ic_delete_key = otus_delete_key; +#endif + + ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, + sizeof(sc->sc_txtap), OTUS_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + OTUS_RX_RADIOTAP_PRESENT); +#endif + sc->ntxchains = + ((sc->txchainmask >> 2) & 1) + + ((sc->txchainmask >> 1) & 1) + + ((sc->txchainmask >> 0) & 1); + sc->nrxchains = + ((sc->rxchainmask >> 2) & 1) + + ((sc->rxchainmask >> 1) & 1) + + ((sc->rxchainmask >> 0) & 1); + + sc->amrr.amrr_min_success_threshold = 1; + sc->amrr.amrr_max_success_threshold = 15; + + device_printf(sc->sc_dev,"%s: Planned end\n", __func__); + + return (0); +} +#endif + +void +athn_detach(struct athn_softc *sc) +{ + // TODO no member named 'ic_if' in 'struct ieee80211com' + // struct ifnet *ifp = &sc->sc_ic.ic_if; + struct ifnet *ifp = NULL; + int qid; +#if OpenBSD_ONLY + timeout_del(&sc->scan_to); + timeout_del(&sc->calib_to); +#endif + if (!(sc->flags & ATHN_FLAG_USB)) { + for (qid = 0; qid < ATHN_QID_COUNT; qid++) + athn_tx_reclaim(sc, qid); + + /* Free Tx/Rx DMA resources. */ + sc->ops.dma_free(sc); + } + /* Free ROM copy. */ + if (sc->eep != NULL) + // free(sc->eep, M_DEVBUF, 0); + free(sc->eep, M_DEVBUF); + + // TODO + // ieee80211_ifdetach(ifp); +#if OpenBSD_IEEE80211_API + if_detach(ifp); +#endif +} + +#if NBPFILTER > 0 +/* + * Attach the interface to 802.11 radiotap. + */ +void +athn_radiotap_attach(struct athn_softc *sc) +{ + bpfattach(&sc->sc_drvbpf, &sc->sc_ic.ic_if, DLT_IEEE802_11_RADIO, + sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN); + + sc->sc_rxtap_len = sizeof(sc->sc_rxtapu); + sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); + sc->sc_rxtap.wr_ihdr.it_present = htole32(ATHN_RX_RADIOTAP_PRESENT); + + sc->sc_txtap_len = sizeof(sc->sc_txtapu); + sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); + sc->sc_txtap.wt_ihdr.it_present = htole32(ATHN_TX_RADIOTAP_PRESENT); +} +#endif + +void +athn_get_chanlist(struct athn_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + uint8_t chan; + int i; + if (sc->flags & ATHN_FLAG_11G) { + for (i = 1; i <= 14; i++) { + chan = i; + ic->ic_channels[chan].ic_freq = + ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ); + ic->ic_channels[chan].ic_flags = + IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | + IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; + if (sc->flags & ATHN_FLAG_11N) + ic->ic_channels[chan].ic_flags |= + IEEE80211_CHAN_HT; + } + } + if (sc->flags & ATHN_FLAG_11A) { + for (i = 0; i < nitems(athn_5ghz_chans); i++) { + chan = athn_5ghz_chans[i]; + ic->ic_channels[chan].ic_freq = + ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ); + ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A; + if (sc->flags & ATHN_FLAG_11N) + ic->ic_channels[chan].ic_flags |= + IEEE80211_CHAN_HT; + } + } +} + +void +athn_rx_start(struct athn_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + uint32_t rfilt; + + /* Setup Rx DMA descriptors. */ + sc->ops.rx_enable(sc); + + /* Set Rx filter. */ + rfilt = AR_RX_FILTER_UCAST | AR_RX_FILTER_BCAST | AR_RX_FILTER_MCAST; + /* Want Compressed Block Ack Requests. */ + rfilt |= AR_RX_FILTER_COMPR_BAR; + rfilt |= AR_RX_FILTER_BEACON; + if (ic->ic_opmode != IEEE80211_M_STA) { + rfilt |= AR_RX_FILTER_PROBEREQ; + if (ic->ic_opmode == IEEE80211_M_MONITOR) + rfilt |= AR_RX_FILTER_PROM; +#ifndef IEEE80211_STA_ONLY + if (AR_SREV_9280_10_OR_LATER(sc) && + ic->ic_opmode == IEEE80211_M_HOSTAP) + rfilt |= AR_RX_FILTER_PSPOLL; +#endif + } + athn_set_rxfilter(sc, rfilt); + + /* Set BSSID mask. */ + AR_WRITE(sc, AR_BSSMSKL, 0xffffffff); + AR_WRITE(sc, AR_BSSMSKU, 0xffff); + + athn_set_opmode(sc); + + /* Set multicast filter. */ + AR_WRITE(sc, AR_MCAST_FIL0, 0xffffffff); + AR_WRITE(sc, AR_MCAST_FIL1, 0xffffffff); + + AR_WRITE(sc, AR_FILT_OFDM, 0); + AR_WRITE(sc, AR_FILT_CCK, 0); + AR_WRITE(sc, AR_MIBC, 0); + AR_WRITE(sc, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); + AR_WRITE(sc, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); + + /* XXX ANI. */ + AR_WRITE(sc, AR_PHY_ERR_1, 0); + AR_WRITE(sc, AR_PHY_ERR_2, 0); + + /* Disable HW crypto for now. */ + AR_SETBITS(sc, AR_DIAG_SW, AR_DIAG_ENCRYPT_DIS | AR_DIAG_DECRYPT_DIS); + + /* Start PCU Rx. */ + AR_CLRBITS(sc, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT); + AR_WRITE_BARRIER(sc); +} + +void +athn_set_rxfilter(struct athn_softc *sc, uint32_t rfilt) +{ + AR_WRITE(sc, AR_RX_FILTER, rfilt); + +#ifdef notyet + reg = AR_READ(sc, AR_PHY_ERR); + reg &= (AR_PHY_ERR_RADAR | AR_PHY_ERR_OFDM_TIMING | + AR_PHY_ERR_CCK_TIMING); + AR_WRITE(sc, AR_PHY_ERR, reg); + if (reg != 0) + AR_SETBITS(sc, AR_RXCFG, AR_RXCFG_ZLFDMA); + else + AR_CLRBITS(sc, AR_RXCFG, AR_RXCFG_ZLFDMA); +#else + AR_WRITE(sc, AR_PHY_ERR, 0); + AR_CLRBITS(sc, AR_RXCFG, AR_RXCFG_ZLFDMA); +#endif + AR_WRITE_BARRIER(sc); +} + +int +athn_intr(void *xsc) +{ + struct athn_softc *sc = xsc; + // TODO no member named 'ic_if' in 'struct ieee80211com' + // struct ifnet *ifp = &sc->sc_ic.ic_if; + struct ifnet *ifp = NULL; +#if OpenBSD_IEEE80211_API + if ((ifp->if_flags & (IFF_UP | IFF_DRV_RUNNING)) != + (IFF_UP | IFF_DRV_RUNNING)) + return (0); +#endif + return (sc->ops.intr(sc)); +} + +void +athn_get_chipid(struct athn_softc *sc) +{ + uint32_t reg; + + ATHN_LOCK(sc); + reg = AR_READ(sc, AR_SREV); + ATHN_UNLOCK(sc); + if (MS(reg, AR_SREV_ID) == 0xff) { + sc->mac_ver = MS(reg, AR_SREV_VERSION2); + sc->mac_rev = MS(reg, AR_SREV_REVISION2); + if (!(reg & AR_SREV_TYPE2_HOST_MODE)) + sc->flags |= ATHN_FLAG_PCIE; + } else { + sc->mac_ver = MS(reg, AR_SREV_VERSION); + sc->mac_rev = MS(reg, AR_SREV_REVISION); + if (sc->mac_ver == AR_SREV_VERSION_5416_PCIE) + sc->flags |= ATHN_FLAG_PCIE; + } +} + +const char * +athn_get_mac_name(struct athn_softc *sc) +{ + switch (sc->mac_ver) { + case AR_SREV_VERSION_5416_PCI: + return ("AR5416"); + case AR_SREV_VERSION_5416_PCIE: + return ("AR5418"); + case AR_SREV_VERSION_9160: + return ("AR9160"); + case AR_SREV_VERSION_9280: + return ("AR9280"); + case AR_SREV_VERSION_9285: + return ("AR9285"); + case AR_SREV_VERSION_9271: + return ("AR9271"); + case AR_SREV_VERSION_9287: + return ("AR9287"); + case AR_SREV_VERSION_9380: + return ("AR9380"); + case AR_SREV_VERSION_9485: + return ("AR9485"); + } + return ("unknown"); +} + +/* + * Return RF chip name (not for single-chip solutions). + */ +const char * +athn_get_rf_name(struct athn_softc *sc) +{ + // TODO improve output + KASSERT(!AR_SINGLE_CHIP(sc), "athn_get_rf_name"); + + switch (sc->rf_rev) { + case AR_RAD5133_SREV_MAJOR: /* Dual-band 3T3R. */ + return ("AR5133"); + case AR_RAD2133_SREV_MAJOR: /* Single-band 3T3R. */ + return ("AR2133"); + case AR_RAD5122_SREV_MAJOR: /* Dual-band 2T2R. */ + return ("AR5122"); + case AR_RAD2122_SREV_MAJOR: /* Single-band 2T2R. */ + return ("AR2122"); + } + return ("unknown"); +} + +int +athn_reset_power_on(struct athn_softc *sc) +{ + int ntries; + + // ATHN_LOCK(sc); + /* Set force wake. */ + AR_WRITE(sc, AR_RTC_FORCE_WAKE, + AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); + + if (!AR_SREV_9380_10_OR_LATER(sc)) { + /* Make sure no DMA is active by doing an AHB reset. */ + AR_WRITE(sc, AR_RC, AR_RC_AHB); + } + /* RTC reset and clear. */ + AR_WRITE(sc, AR_RTC_RESET, 0); + AR_WRITE_BARRIER(sc); + DELAY(2); + if (!AR_SREV_9380_10_OR_LATER(sc)) + AR_WRITE(sc, AR_RC, 0); + AR_WRITE(sc, AR_RTC_RESET, 1); + + /* Poll until RTC is ON. */ + for (ntries = 0; ntries < 1000; ntries++) { + if ((AR_READ(sc, AR_RTC_STATUS) & AR_RTC_STATUS_M) == + AR_RTC_STATUS_ON) + break; + DELAY(10); + } + // ATHN_UNLOCK(sc); + if (ntries == 1000) { + DPRINTF(("RTC not waking up\n")); + return (ETIMEDOUT); + } + return (athn_reset(sc, 0)); +} + +int +athn_reset(struct athn_softc *sc, int cold) +{ + int ntries; + + // ATHN_LOCK(sc); + /* Set force wake. */ + AR_WRITE(sc, AR_RTC_FORCE_WAKE, + AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); + + if (AR_READ(sc, AR_INTR_SYNC_CAUSE) & + (AR_INTR_SYNC_LOCAL_TIMEOUT | AR_INTR_SYNC_RADM_CPL_TIMEOUT)) { + AR_WRITE(sc, AR_INTR_SYNC_ENABLE, 0); + AR_WRITE(sc, AR_RC, AR_RC_HOSTIF | + (!AR_SREV_9380_10_OR_LATER(sc) ? AR_RC_AHB : 0)); + } else if (!AR_SREV_9380_10_OR_LATER(sc)) + AR_WRITE(sc, AR_RC, AR_RC_AHB); + + AR_WRITE(sc, AR_RTC_RC, AR_RTC_RC_MAC_WARM | + (cold ? AR_RTC_RC_MAC_COLD : 0)); + AR_WRITE_BARRIER(sc); + DELAY(50); + AR_WRITE(sc, AR_RTC_RC, 0); + for (ntries = 0; ntries < 1000; ntries++) { + if (!(AR_READ(sc, AR_RTC_RC) & + (AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD))) + break; + DELAY(10); + } + if (ntries == 1000) { + ATHN_UNLOCK(sc); + DPRINTF(("RTC stuck in MAC reset\n")); + return (ETIMEDOUT); + } + AR_WRITE(sc, AR_RC, 0); + AR_WRITE_BARRIER(sc); + // ATHN_UNLOCK(sc); + return (0); +} + +int +athn_set_power_awake(struct athn_softc *sc) +{ + int ntries, error; + + // ATHN_LOCK(sc); + /* Do a Power-On-Reset if shutdown. */ + if ((AR_READ(sc, AR_RTC_STATUS) & AR_RTC_STATUS_M) == + AR_RTC_STATUS_SHUTDOWN) { + if ((error = athn_reset_power_on(sc)) != 0) { + ATHN_UNLOCK(sc); + return (error); + } + if (!AR_SREV_9380_10_OR_LATER(sc)) + athn_init_pll(sc, NULL); + } + AR_SETBITS(sc, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); + AR_WRITE_BARRIER(sc); + DELAY(50); /* Give chip the chance to awake. */ + + /* Poll until RTC is ON. */ + for (ntries = 0; ntries < 4000; ntries++) { + if ((AR_READ(sc, AR_RTC_STATUS) & AR_RTC_STATUS_M) == + AR_RTC_STATUS_ON) + break; + DELAY(50); + AR_SETBITS(sc, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); + } + if (ntries == 4000) { + DPRINTF(("RTC not waking up\n")); + ATHN_UNLOCK(sc); + return (ETIMEDOUT); + } + + AR_CLRBITS(sc, AR_STA_ID1, AR_STA_ID1_PWR_SAV); + AR_WRITE_BARRIER(sc); + // ATHN_UNLOCK(sc); + return (0); +} + +void +athn_set_power_sleep(struct athn_softc *sc) +{ + // ATHN_LOCK(sc); + AR_SETBITS(sc, AR_STA_ID1, AR_STA_ID1_PWR_SAV); + /* Allow the MAC to go to sleep. */ + AR_CLRBITS(sc, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); + if (!AR_SREV_9380_10_OR_LATER(sc)) + AR_WRITE(sc, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); + /* + * NB: Clearing RTC_RESET_EN when setting the chip to sleep mode + * results in high power consumption on AR5416 chipsets. + */ + if (!AR_SREV_5416(sc) && !AR_SREV_9271(sc)) + AR_CLRBITS(sc, AR_RTC_RESET, AR_RTC_RESET_EN); + AR_WRITE_BARRIER(sc); + // ATHN_UNLOCK(sc); +} + +void +athn_init_pll(struct athn_softc *sc, const struct ieee80211_channel *c) +{ + uint32_t pll; + + // ATHN_LOCK(sc); + if (AR_SREV_9380_10_OR_LATER(sc)) { + if (AR_SREV_9485(sc)) + AR_WRITE(sc, AR_RTC_PLL_CONTROL2, 0x886666); + pll = SM(AR_RTC_9160_PLL_REFDIV, 0x5); + pll |= SM(AR_RTC_9160_PLL_DIV, 0x2c); + } else if (AR_SREV_9280_10_OR_LATER(sc)) { + pll = SM(AR_RTC_9160_PLL_REFDIV, 0x05); + if (c != NULL && IEEE80211_IS_CHAN_5GHZ(c)) { + if (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK) + pll = 0x142c; + else if (AR_SREV_9280_20(sc)) + pll = 0x2850; + else + pll |= SM(AR_RTC_9160_PLL_DIV, 0x28); + } else + pll |= SM(AR_RTC_9160_PLL_DIV, 0x2c); + } else if (AR_SREV_9160_10_OR_LATER(sc)) { + pll = SM(AR_RTC_9160_PLL_REFDIV, 0x05); + if (c != NULL && IEEE80211_IS_CHAN_5GHZ(c)) + pll |= SM(AR_RTC_9160_PLL_DIV, 0x50); + else + pll |= SM(AR_RTC_9160_PLL_DIV, 0x58); + } else { + pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2; + if (c != NULL && IEEE80211_IS_CHAN_5GHZ(c)) + pll |= SM(AR_RTC_PLL_DIV, 0x0a); + else + pll |= SM(AR_RTC_PLL_DIV, 0x0b); + } + DPRINTFN(5, ("AR_RTC_PLL_CONTROL=0x%08x\n", pll)); + AR_WRITE(sc, AR_RTC_PLL_CONTROL, pll); + if (AR_SREV_9271(sc)) { + /* Switch core clock to 117MHz. */ + AR_WRITE_BARRIER(sc); + DELAY(500); + AR_WRITE(sc, AR9271_CLOCK_CONTROL, 0x304); + } + AR_WRITE_BARRIER(sc); + DELAY(100); + AR_WRITE(sc, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); + AR_WRITE_BARRIER(sc); + // ATHN_UNLOCK(sc); +} + +void +athn_write_serdes(struct athn_softc *sc, const struct athn_serdes *serdes) +{ + int i; + + /* Write sequence to Serializer/Deserializer. */ + // ATHN_LOCK(sc); + for (i = 0; i < serdes->nvals; i++) + AR_WRITE(sc, serdes->regs[i], serdes->vals[i]); + AR_WRITE_BARRIER(sc); + // ATHN_UNLOCK(sc); +} + +void +athn_config_pcie(struct athn_softc *sc) +{ + /* Disable PLL when in L0s as well as receiver clock when in L1. */ + athn_write_serdes(sc, sc->serdes); + + DELAY(1000); + ATHN_LOCK(sc); + /* Allow forcing of PCIe core into L1 state. */ + AR_SETBITS(sc, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); + +#ifndef ATHN_PCIE_WAEN + AR_WRITE(sc, AR_WA, sc->workaround); +#else + AR_WRITE(sc, AR_WA, ATHN_PCIE_WAEN); +#endif + AR_WRITE_BARRIER(sc); + ATHN_UNLOCK(sc); +} + +/* + * Serializer/Deserializer programming for non-PCIe devices. + */ +static const uint32_t ar_nonpcie_serdes_regs[] = { + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES2, +}; + +static const uint32_t ar_nonpcie_serdes_vals[] = { + 0x9248fc00, + 0x24924924, + 0x28000029, + 0x57160824, + 0x25980579, + 0x00000000, + 0x1aaabe40, + 0xbe105554, + 0x000e1007, + 0x00000000 +}; + +static const struct athn_serdes ar_nonpcie_serdes = { + nitems(ar_nonpcie_serdes_vals), + ar_nonpcie_serdes_regs, + ar_nonpcie_serdes_vals +}; + +void +athn_config_nonpcie(struct athn_softc *sc) +{ + athn_write_serdes(sc, &ar_nonpcie_serdes); +} + +int +athn_set_chan(struct athn_softc *sc, struct ieee80211_channel *c, + struct ieee80211_channel *extc) +{ + struct athn_ops *ops = &sc->ops; + int error, qid; + + /* Check that Tx is stopped, otherwise RF Bus grant will not work. */ + for (qid = 0; qid < ATHN_QID_COUNT; qid++) + if (athn_tx_pending(sc, qid)) + return (EBUSY); + + /* Request RF Bus grant. */ + if ((error = ops->rf_bus_request(sc)) != 0) + return (error); + + ops->set_phy(sc, c, extc); + + /* Change the synthesizer. */ + if ((error = ops->set_synth(sc, c, extc)) != 0) + return (error); + + sc->curchan = c; + sc->curchanext = extc; + + /* Set transmit power values for new channel. */ + ops->set_txpower(sc, c, extc); + + /* Release the RF Bus grant. */ + ops->rf_bus_release(sc); + + /* Write delta slope coeffs for modes where OFDM may be used. */ + if (sc->sc_ic.ic_curmode != IEEE80211_MODE_11B) + ops->set_delta_slope(sc, c, extc); + + ops->spur_mitigate(sc, c, extc); + + return (0); +} + +int +athn_switch_chan(struct athn_softc *sc, struct ieee80211_channel *c, + struct ieee80211_channel *extc) +{ + int error, qid; + + /* Disable interrupts. */ + athn_disable_interrupts(sc); + + /* Stop all Tx queues. */ + for (qid = 0; qid < ATHN_QID_COUNT; qid++) + athn_stop_tx_dma(sc, qid); + for (qid = 0; qid < ATHN_QID_COUNT; qid++) + athn_tx_reclaim(sc, qid); + + /* Stop Rx. */ + AR_SETBITS(sc, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT); + AR_WRITE(sc, AR_MIBC, AR_MIBC_FMC); + AR_WRITE(sc, AR_MIBC, AR_MIBC_CMC); + AR_WRITE(sc, AR_FILT_OFDM, 0); + AR_WRITE(sc, AR_FILT_CCK, 0); + athn_set_rxfilter(sc, 0); + error = athn_stop_rx_dma(sc); + if (error != 0) + goto reset; + +#ifdef notyet + /* AR9280 needs a full reset. */ + if (AR_SREV_9280(sc)) +#endif + goto reset; + + /* If band or bandwidth changes, we need to do a full reset. */ + if (c->ic_flags != sc->curchan->ic_flags || + ((extc != NULL) ^ (sc->curchanext != NULL))) { + DPRINTFN(2, ("channel band switch\n")); + goto reset; + } + error = athn_set_power_awake(sc); + if (error != 0) + goto reset; + + error = athn_set_chan(sc, c, extc); + if (error != 0) { + reset: /* Error found, try a full reset. */ + DPRINTFN(3, ("needs a full reset\n")); + error = athn_hw_reset(sc, c, extc, 0); + if (error != 0) /* Hopeless case. */ + return (error); + } + athn_rx_start(sc); + + /* Re-enable interrupts. */ + athn_enable_interrupts(sc); + return (0); +} + +void +athn_get_delta_slope(uint32_t coeff, uint32_t *exponent, uint32_t *mantissa) +{ +#define COEFF_SCALE_SHIFT 24 + uint32_t exp, man; + + /* exponent = 14 - floor(log2(coeff)) */ + for (exp = 31; exp > 0; exp--) + if (coeff & (1 << exp)) + break; + exp = 14 - (exp - COEFF_SCALE_SHIFT); + + /* mantissa = floor(coeff * 2^exponent + 0.5) */ + man = coeff + (1 << (COEFF_SCALE_SHIFT - exp - 1)); + + *mantissa = man >> (COEFF_SCALE_SHIFT - exp); + *exponent = exp - 16; +#undef COEFF_SCALE_SHIFT +} + +void +athn_reset_key(struct athn_softc *sc, int entry) +{ + /* + * NB: Key cache registers access special memory area that requires + * two 32-bit writes to actually update the values in the internal + * memory. Consequently, writes must be grouped by pair. + * + * All writes to registers with an offset of 0x0 or 0x8 write to a + * temporary register. A write to a register with an offset of 0x4 + * or 0xc writes concatenates the written value with the value in + * the temporary register and writes the result to key cache memory. + * The actual written memory area is 50 bits wide. + */ + AR_WRITE(sc, AR_KEYTABLE_KEY0(entry), 0); + AR_WRITE(sc, AR_KEYTABLE_KEY1(entry), 0); + + AR_WRITE(sc, AR_KEYTABLE_KEY2(entry), 0); + AR_WRITE(sc, AR_KEYTABLE_KEY3(entry), 0); + + AR_WRITE(sc, AR_KEYTABLE_KEY4(entry), 0); + AR_WRITE(sc, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); + + AR_WRITE(sc, AR_KEYTABLE_MAC0(entry), 0); + AR_WRITE(sc, AR_KEYTABLE_MAC1(entry), 0); + + AR_WRITE_BARRIER(sc); +} + +// TODO? +int +athn_set_key(struct ieee80211com *ic, struct ieee80211_node *ni, + struct ieee80211_key *k) +{ + struct athn_softc *sc = ic->ic_softc; + const uint8_t *key = NULL; + // const uint8_t *addr; + uintptr_t entry; + uint32_t lo, hi, unicast; + lo = 0; hi = 0; // TODO remove + + // TODO no member named 'k_cipher' in 'struct ieee80211_key' + // if (k->k_cipher != IEEE80211_CIPHER_CCMP) { + // /* Use software crypto for ciphers other than CCMP. */ + // return ieee80211_set_key(ic, ni, k); + // } + + // TODO no member named 'k_flags' in 'struct ieee80211_key' +// if (!(k->k_flags & IEEE80211_KEY_GROUP)) { +// #ifndef IEEE80211_STA_ONLY +// if (ic->ic_opmode == IEEE80211_M_HOSTAP) +// entry = IEEE80211_WEP_NKID + IEEE80211_AID(ni->ni_associd); +// else +// #endif +// entry = IEEE80211_WEP_NKID; +// if (entry >= sc->kc_entries - IEEE80211_WEP_NKID) +// return ENOSPC; +// } else { +// entry = k->k_id; +// if (entry >= IEEE80211_WEP_NKID) +// return ENOSPC; +// } + // TODO no member named 'k_priv' in 'struct ieee80211_key' + // k->k_priv = (void *)entry; + + /* NB: See note about key cache registers access above. */ + // TODO no member named 'k_key' in 'struct ieee80211_key' + // key = k->k_key; + entry = 0; // TODO remove + + AR_WRITE(sc, AR_KEYTABLE_KEY0(entry), LE_READ_4(&key[ 0])); + AR_WRITE(sc, AR_KEYTABLE_KEY1(entry), LE_READ_2(&key[ 4])); + + AR_WRITE(sc, AR_KEYTABLE_KEY2(entry), LE_READ_4(&key[ 6])); + AR_WRITE(sc, AR_KEYTABLE_KEY3(entry), LE_READ_2(&key[10])); + + AR_WRITE(sc, AR_KEYTABLE_KEY4(entry), LE_READ_4(&key[12])); + AR_WRITE(sc, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CCM); + + unicast = AR_KEYTABLE_VALID; + // TODO no member named 'k_flags' in 'struct ieee80211_key' +// if (!(k->k_flags & IEEE80211_KEY_GROUP)) { +// addr = ni->ni_macaddr; +// lo = LE_READ_4(&addr[0]); +// hi = LE_READ_2(&addr[4]); +// lo = lo >> 1 | hi << 31; +// hi = hi >> 1; +// } else { +// #ifndef IEEE80211_STA_ONLY +// if (ic->ic_opmode == IEEE80211_M_HOSTAP) { +// uint8_t groupaddr[ETHER_ADDR_LEN]; +// IEEE80211_ADDR_COPY(groupaddr, ic->ic_myaddr); +// groupaddr[0] |= 0x01; +// lo = LE_READ_4(&groupaddr[0]); +// hi = LE_READ_2(&groupaddr[4]); +// lo = lo >> 1 | hi << 31; +// hi = hi >> 1; +// /* +// * KEYTABLE_VALID indicates that the address +// * is a unicast address which must match the +// * transmitter address when decrypting frames. +// * Not setting KEYTABLE_VALID allows hardware to +// * use this key for multicast frame decryption. +// */ +// unicast = 0; +// } else +// #endif +// lo = hi = 0; +// } + AR_WRITE(sc, AR_KEYTABLE_MAC0(entry), lo); + AR_WRITE(sc, AR_KEYTABLE_MAC1(entry), hi | unicast); + + AR_WRITE_BARRIER(sc); + + /* Enable HW crypto. */ + AR_CLRBITS(sc, AR_DIAG_SW, AR_DIAG_ENCRYPT_DIS | AR_DIAG_DECRYPT_DIS); + + AR_WRITE_BARRIER(sc); + return (0); +} + +void +athn_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, + struct ieee80211_key *k) +{ + // struct athn_softc *sc = ic->ic_softc; + // uintptr_t entry; + + // TODO no member named 'k_cipher' in 'struct ieee80211_key' + // if (k->k_cipher == IEEE80211_CIPHER_CCMP) { + // entry = (uintptr_t)k->k_priv; + // athn_reset_key(sc, entry); + // explicit_bzero(k, sizeof(*k)); + // } else + // ieee80211_delete_key(ic, ni, k); +} + +void +athn_led_init(struct athn_softc *sc) +{ + struct athn_ops *ops = &sc->ops; + + // ATHN_LOCK(sc); + ops->gpio_config_output(sc, sc->led_pin, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); + /* LED off, active low. */ + // ATHN_UNLOCK(sc); + athn_set_led(sc, 0); +} + +void +athn_set_led(struct athn_softc *sc, int on) +{ + struct athn_ops *ops = &sc->ops; + + // ATHN_LOCK(sc); + sc->led_state = on; + ops->gpio_write(sc, sc->led_pin, !sc->led_state); + // ATHN_UNLOCK(sc); +} + +#ifdef ATHN_BT_COEXISTENCE +void +athn_btcoex_init(struct athn_softc *sc) +{ + struct athn_ops *ops = &sc->ops; + uint32_t reg; + + if (sc->flags & ATHN_FLAG_BTCOEX2WIRE) { + /* Connect bt_active to baseband. */ + AR_CLRBITS(sc, sc->gpio_input_en_off, + AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF | + AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF); + AR_SETBITS(sc, sc->gpio_input_en_off, + AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB); + + reg = AR_READ(sc, AR_GPIO_INPUT_MUX1); + reg = RW(reg, AR_GPIO_INPUT_MUX1_BT_ACTIVE, + AR_GPIO_BTACTIVE_PIN); + AR_WRITE(sc, AR_GPIO_INPUT_MUX1, reg); + AR_WRITE_BARRIER(sc); + + ops->gpio_config_input(sc, AR_GPIO_BTACTIVE_PIN); + } else { /* 3-wire. */ + AR_SETBITS(sc, sc->gpio_input_en_off, + AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB | + AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB); + + reg = AR_READ(sc, AR_GPIO_INPUT_MUX1); + reg = RW(reg, AR_GPIO_INPUT_MUX1_BT_ACTIVE, + AR_GPIO_BTACTIVE_PIN); + reg = RW(reg, AR_GPIO_INPUT_MUX1_BT_PRIORITY, + AR_GPIO_BTPRIORITY_PIN); + AR_WRITE(sc, AR_GPIO_INPUT_MUX1, reg); + AR_WRITE_BARRIER(sc); + + ops->gpio_config_input(sc, AR_GPIO_BTACTIVE_PIN); + ops->gpio_config_input(sc, AR_GPIO_BTPRIORITY_PIN); + } +} + +void +athn_btcoex_enable(struct athn_softc *sc) +{ + struct athn_ops *ops = &sc->ops; + uint32_t reg; + + if (sc->flags & ATHN_FLAG_BTCOEX3WIRE) { + AR_WRITE(sc, AR_BT_COEX_MODE, + SM(AR_BT_MODE, AR_BT_MODE_SLOTTED) | + SM(AR_BT_PRIORITY_TIME, 2) | + SM(AR_BT_FIRST_SLOT_TIME, 5) | + SM(AR_BT_QCU_THRESH, ATHN_QID_AC_BE) | + AR_BT_TXSTATE_EXTEND | AR_BT_TX_FRAME_EXTEND | + AR_BT_QUIET | AR_BT_RX_CLEAR_POLARITY); + AR_WRITE(sc, AR_BT_COEX_WEIGHT, + SM(AR_BTCOEX_BT_WGHT, AR_STOMP_LOW_BT_WGHT) | + SM(AR_BTCOEX_WL_WGHT, AR_STOMP_LOW_WL_WGHT)); + AR_WRITE(sc, AR_BT_COEX_MODE2, + SM(AR_BT_BCN_MISS_THRESH, 50) | + AR_BT_HOLD_RX_CLEAR | AR_BT_DISABLE_BT_ANT); + + AR_SETBITS(sc, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE); + AR_CLRBITS(sc, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX); + AR_WRITE_BARRIER(sc); + + ops->gpio_config_output(sc, AR_GPIO_WLANACTIVE_PIN, + AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL); + + } else { /* 2-wire. */ + ops->gpio_config_output(sc, AR_GPIO_WLANACTIVE_PIN, + AR_GPIO_OUTPUT_MUX_AS_TX_FRAME); + } + reg = AR_READ(sc, AR_GPIO_PDPU); + reg &= ~(0x3 << (AR_GPIO_WLANACTIVE_PIN * 2)); + reg |= 0x2 << (AR_GPIO_WLANACTIVE_PIN * 2); + AR_WRITE(sc, AR_GPIO_PDPU, reg); + AR_WRITE_BARRIER(sc); + + /* Disable PCIe Active State Power Management (ASPM). */ + if (sc->sc_disable_aspm != NULL) + sc->sc_disable_aspm(sc); + + /* XXX Start periodic timer. */ +} + +void +athn_btcoex_disable(struct athn_softc *sc) +{ + struct athn_ops *ops = &sc->ops; + + ops->gpio_write(sc, AR_GPIO_WLANACTIVE_PIN, 0); + + ops->gpio_config_output(sc, AR_GPIO_WLANACTIVE_PIN, + AR_GPIO_OUTPUT_MUX_AS_OUTPUT); + + if (sc->flags & ATHN_FLAG_BTCOEX3WIRE) { + AR_WRITE(sc, AR_BT_COEX_MODE, + SM(AR_BT_MODE, AR_BT_MODE_DISABLED) | AR_BT_QUIET); + AR_WRITE(sc, AR_BT_COEX_WEIGHT, 0); + AR_WRITE(sc, AR_BT_COEX_MODE2, 0); + /* XXX Stop periodic timer. */ + } + AR_WRITE_BARRIER(sc); + /* XXX Restore ASPM setting? */ +} +#endif + +// TODO: not sure if needed +void +athn_iter_calib(void *arg, struct ieee80211_node *ni) +{ + // struct athn_softc *sc = arg; + // struct athn_node *an = (struct athn_node *)ni; + + // TODO implicit declaration of function 'ieee80211_amrr_choose' + // if ((ni->ni_flags & IEEE80211_NODE_HT) == 0) + // ieee80211_amrr_choose(&sc->amrr, ni, &an->amn); +} + +// TODO: not sure if needed +int +athn_cap_noisefloor(struct athn_softc *sc, int nf) +{ + int16_t min, max; + min = max = 0; //TODO remove + + if (nf == 0 || nf == -1) /* invalid measurement */ + return AR_DEFAULT_NOISE_FLOOR; + + // TODO no member named 'ic_bss' in 'struct ieee80211com' + // if (IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_bss->ni_chan)) { + // min = sc->cca_min_2g; + // max = sc->cca_max_2g; + // } else { + // min = sc->cca_min_5g; + // max = sc->cca_max_5g; + // } + + if (nf < min) + return min; + if (nf > max) + return max; + + return nf; +} + +int +athn_nf_hist_mid(int *nf_vals, int nvalid) +{ + int nf_sorted[ATHN_NF_CAL_HIST_MAX]; + int i, j, nf; + + if (nvalid <= 1) + return nf_vals[0]; + + for (i = 0; i < nvalid; i++) + nf_sorted[i] = nf_vals[i]; + + for (i = 0; i < nvalid; i++) { + for (j = 1; j < nvalid - i; j++) { + if (nf_sorted[j] > nf_sorted[j - 1]) { + nf = nf_sorted[j]; + nf_sorted[j] = nf_sorted[j - 1]; + nf_sorted[j - 1] = nf; + } + } + } + + return nf_sorted[nvalid / 2]; +} + +void +athn_filter_noisefloor(struct athn_softc *sc) +{ + int nf_vals[ATHN_NF_CAL_HIST_MAX]; + int nf_ext_vals[ATHN_NF_CAL_HIST_MAX]; + int i, cur, n; + + for (i = 0; i < sc->nrxchains; i++) { + if (sc->nf_hist_cur > 0) + cur = sc->nf_hist_cur - 1; + else + cur = ATHN_NF_CAL_HIST_MAX - 1; + for (n = 0; n < sc->nf_hist_nvalid; n++) { + nf_vals[n] = sc->nf_hist[cur].nf[i]; + nf_ext_vals[n] = sc->nf_hist[cur].nf_ext[i]; + if (++cur >= ATHN_NF_CAL_HIST_MAX) + cur = 0; + } + sc->nf_priv[i] = athn_cap_noisefloor(sc, + athn_nf_hist_mid(nf_vals, sc->nf_hist_nvalid)); + sc->nf_ext_priv[i] = athn_cap_noisefloor(sc, + athn_nf_hist_mid(nf_ext_vals, sc->nf_hist_nvalid)); + } +} + +void +athn_start_noisefloor_calib(struct athn_softc *sc, int reset_history) +{ + extern volatile int ticks; + + if (reset_history) + sc->nf_hist_nvalid = 0; + + sc->nf_calib_pending = 1; + sc->nf_calib_ticks = ticks; + + sc->ops.noisefloor_calib(sc); +} + +void +athn_calib_to(void *arg) +{ + extern volatile int ticks; + struct athn_softc *sc = arg; + struct athn_ops *ops = &sc->ops; + __attribute__((unused)) struct ieee80211com *ic = &sc->sc_ic; + int s; + + s = splnet(); + + /* Do periodic (every 4 minutes) PA calibration. */ + if ((ticks - (sc->pa_calib_ticks + 240 * hz)) >= 0) { + sc->pa_calib_ticks = ticks; + if (AR_SREV_9271(sc)) + ar9271_pa_calib(sc); + } + + /* Do periodic (every 4 minutes) NF calibration. */ + if (sc->nf_calib_pending && ops->get_noisefloor(sc)) { + if (sc->nf_hist_nvalid < ATHN_NF_CAL_HIST_MAX) + sc->nf_hist_nvalid++; + athn_filter_noisefloor(sc); + ops->apply_noisefloor(sc); + sc->nf_calib_pending = 0; + } + if (ticks - (sc->nf_calib_ticks + 240 * hz) >= 0) + athn_start_noisefloor_calib(sc, 0); + + /* Do periodic (every 30 seconds) temperature compensation. */ + if ((sc->flags & ATHN_FLAG_OLPC) && + ticks >= sc->olpc_ticks + 30 * hz) { + sc->olpc_ticks = ticks; + ops->olpc_temp_compensation(sc); + } + +#ifdef notyet + /* XXX ANI. */ + athn_ani_monitor(sc); +#endif + + /* Do periodic (every 30 seconds) ADC/IQ calibration. */ + if (sc->cur_calib_mask != 0) { + ops->next_calib(sc); + sc->iqcal_ticks = ticks; + } else if (sc->sup_calib_mask != 0 && + ticks >= sc->iqcal_ticks + 30 * hz) { + memset(&sc->calib, 0, sizeof(sc->calib)); + sc->cur_calib_mask = sc->sup_calib_mask; + ops->do_calib(sc); + sc->iqcal_ticks = ticks; + } + + // TODO no member named 'ic_fixed_rate' in 'struct ieee80211com' + // if (ic->ic_fixed_rate == -1) { + // if (ic->ic_opmode == IEEE80211_M_STA) + // athn_iter_calib(sc, ic->ic_bss); + // else + // ieee80211_iterate_nodes(ic, athn_iter_calib, sc); + // } +#if OpenBSD_ONLY + timeout_add_msec(&sc->calib_to, 500); +#endif + splx(s); +} + +int +athn_init_calib(struct athn_softc *sc, struct ieee80211_channel *c, + struct ieee80211_channel *extc) +{ + struct athn_ops *ops = &sc->ops; + int error; + + if (AR_SREV_9285_10_OR_LATER(sc)) + error = ar9285_init_calib(sc, c, extc); + if (error != 0) + return (error); + + if (AR_SREV_9285_11_OR_LATER(sc)) { + extern volatile int ticks; + sc->pa_calib_ticks = ticks; + if (AR_SREV_9271(sc)) + ar9271_pa_calib(sc); + } + + /* Do noisefloor calibration. */ + ops->init_noisefloor_calib(sc); + + if (AR_SREV_9160_10_OR_LATER(sc)) { + /* Support IQ calibration. */ + sc->sup_calib_mask = ATHN_CAL_IQ; + if (AR_SREV_9380_10_OR_LATER(sc)) { + /* Support temperature compensation calibration. */ + sc->sup_calib_mask |= ATHN_CAL_TEMP; + } else if (IEEE80211_IS_CHAN_5GHZ(c) || extc != NULL) { + /* + * ADC gain calibration causes uplink throughput + * drops in HT40 mode on AR9287. + */ + if (!AR_SREV_9287(sc)) { + /* Support ADC gain calibration. */ + sc->sup_calib_mask |= ATHN_CAL_ADC_GAIN; + } + /* Support ADC DC offset calibration. */ + sc->sup_calib_mask |= ATHN_CAL_ADC_DC; + } + } + return (0); +} + +/* + * Adaptive noise immunity. + */ +int32_t +athn_ani_get_rssi(struct athn_softc *sc) +{ + return (0); /* XXX */ +} + +void +athn_ani_ofdm_err_trigger(struct athn_softc *sc) +{ + struct athn_ani *ani = &sc->ani; + struct athn_ops *ops = &sc->ops; + int32_t rssi; + + /* First, raise noise immunity level, up to max. */ + if (ani->noise_immunity_level < 4) { + ani->noise_immunity_level++; + ops->set_noise_immunity_level(sc, ani->noise_immunity_level); + return; + } + + /* Then, raise our spur immunity level, up to max. */ + if (ani->spur_immunity_level < 7) { + ani->spur_immunity_level++; + ops->set_spur_immunity_level(sc, ani->spur_immunity_level); + return; + } + +#ifndef IEEE80211_STA_ONLY + if (sc->sc_ic.ic_opmode == IEEE80211_M_HOSTAP) { + if (ani->firstep_level < 2) { + ani->firstep_level++; + ops->set_firstep_level(sc, ani->firstep_level); + } + return; + } +#endif + rssi = athn_ani_get_rssi(sc); + if (rssi > ATHN_ANI_RSSI_THR_HIGH) { + /* + * Beacon RSSI is high, turn off OFDM weak signal detection + * or raise first step level as last resort. + */ + if (ani->ofdm_weak_signal) { + ani->ofdm_weak_signal = 0; + ops->disable_ofdm_weak_signal(sc); + ani->spur_immunity_level = 0; + ops->set_spur_immunity_level(sc, 0); + } else if (ani->firstep_level < 2) { + ani->firstep_level++; + ops->set_firstep_level(sc, ani->firstep_level); + } + } else if (rssi > ATHN_ANI_RSSI_THR_LOW) { + /* + * Beacon RSSI is in mid range, we need OFDM weak signal + * detection but we can raise first step level. + */ + if (!ani->ofdm_weak_signal) { + ani->ofdm_weak_signal = 1; + ops->enable_ofdm_weak_signal(sc); + } + if (ani->firstep_level < 2) { + ani->firstep_level++; + ops->set_firstep_level(sc, ani->firstep_level); + } + } // TODO no member named 'ic_bss' in 'struct ieee80211com' + // } else if (IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_bss->ni_chan)) { + // /* + // * Beacon RSSI is low, if in b/g mode, turn off OFDM weak + // * signal detection and zero first step level to maximize + // * CCK sensitivity. + // */ + // if (ani->ofdm_weak_signal) { + // ani->ofdm_weak_signal = 0; + // ops->disable_ofdm_weak_signal(sc); + // } + // if (ani->firstep_level > 0) { + // ani->firstep_level = 0; + // ops->set_firstep_level(sc, 0); + // } + // } +} + +void +athn_ani_cck_err_trigger(struct athn_softc *sc) +{ + struct athn_ani *ani = &sc->ani; + struct athn_ops *ops = &sc->ops; + int32_t rssi; + + /* Raise noise immunity level, up to max. */ + if (ani->noise_immunity_level < 4) { + ani->noise_immunity_level++; + ops->set_noise_immunity_level(sc, ani->noise_immunity_level); + return; + } + +#ifndef IEEE80211_STA_ONLY + if (sc->sc_ic.ic_opmode == IEEE80211_M_HOSTAP) { + if (ani->firstep_level < 2) { + ani->firstep_level++; + ops->set_firstep_level(sc, ani->firstep_level); + } + return; + } +#endif + rssi = athn_ani_get_rssi(sc); + if (rssi > ATHN_ANI_RSSI_THR_LOW) { + /* + * Beacon RSSI is in mid or high range, raise first step + * level. + */ + if (ani->firstep_level < 2) { + ani->firstep_level++; + ops->set_firstep_level(sc, ani->firstep_level); + } + } // TODO no member named 'ic_bss' in 'struct ieee80211com' + // } else if (IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_bss->ni_chan)) { + // /* + // * Beacon RSSI is low, zero first step level to maximize + // * CCK sensitivity. + // */ + // if (ani->firstep_level > 0) { + // ani->firstep_level = 0; + // ops->set_firstep_level(sc, 0); + // } + // } +} + +void +athn_ani_lower_immunity(struct athn_softc *sc) +{ + struct athn_ani *ani = &sc->ani; + struct athn_ops *ops = &sc->ops; + int32_t rssi; + +#ifndef IEEE80211_STA_ONLY + if (sc->sc_ic.ic_opmode == IEEE80211_M_HOSTAP) { + if (ani->firstep_level > 0) { + ani->firstep_level--; + ops->set_firstep_level(sc, ani->firstep_level); + } + return; + } +#endif + rssi = athn_ani_get_rssi(sc); + if (rssi > ATHN_ANI_RSSI_THR_HIGH) { + /* + * Beacon RSSI is high, leave OFDM weak signal detection + * off or it may oscillate. + */ + } else if (rssi > ATHN_ANI_RSSI_THR_LOW) { + /* + * Beacon RSSI is in mid range, turn on OFDM weak signal + * detection or lower first step level. + */ + if (!ani->ofdm_weak_signal) { + ani->ofdm_weak_signal = 1; + ops->enable_ofdm_weak_signal(sc); + return; + } + if (ani->firstep_level > 0) { + ani->firstep_level--; + ops->set_firstep_level(sc, ani->firstep_level); + return; + } + } else { + /* Beacon RSSI is low, lower first step level. */ + if (ani->firstep_level > 0) { + ani->firstep_level--; + ops->set_firstep_level(sc, ani->firstep_level); + return; + } + } + /* + * Lower spur immunity level down to zero, or if all else fails, + * lower noise immunity level down to zero. + */ + if (ani->spur_immunity_level > 0) { + ani->spur_immunity_level--; + ops->set_spur_immunity_level(sc, ani->spur_immunity_level); + } else if (ani->noise_immunity_level > 0) { + ani->noise_immunity_level--; + ops->set_noise_immunity_level(sc, ani->noise_immunity_level); + } +} + +void +athn_ani_restart(struct athn_softc *sc) +{ + struct athn_ani *ani = &sc->ani; + + AR_WRITE(sc, AR_PHY_ERR_1, 0); + AR_WRITE(sc, AR_PHY_ERR_2, 0); + AR_WRITE(sc, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); + AR_WRITE(sc, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); + AR_WRITE_BARRIER(sc); + + ani->listen_time = 0; + ani->ofdm_phy_err_count = 0; + ani->cck_phy_err_count = 0; +} + +void +athn_ani_monitor(struct athn_softc *sc) +{ + struct athn_ani *ani = &sc->ani; + uint32_t cyccnt, txfcnt, rxfcnt, phy1, phy2; + int32_t cycdelta, txfdelta, rxfdelta; + int32_t listen_time; + + txfcnt = AR_READ(sc, AR_TFCNT); /* Tx frame count. */ + rxfcnt = AR_READ(sc, AR_RFCNT); /* Rx frame count. */ + cyccnt = AR_READ(sc, AR_CCCNT); /* Cycle count. */ + + if (ani->cyccnt != 0 && ani->cyccnt <= cyccnt) { + cycdelta = cyccnt - ani->cyccnt; + txfdelta = txfcnt - ani->txfcnt; + rxfdelta = rxfcnt - ani->rxfcnt; + + listen_time = (cycdelta - txfdelta - rxfdelta) / + (athn_clock_rate(sc) * 1000); + } else + listen_time = 0; + + ani->cyccnt = cyccnt; + ani->txfcnt = txfcnt; + ani->rxfcnt = rxfcnt; + + if (listen_time < 0) { + athn_ani_restart(sc); + return; + } + ani->listen_time += listen_time; + + phy1 = AR_READ(sc, AR_PHY_ERR_1); + phy2 = AR_READ(sc, AR_PHY_ERR_2); + + if (phy1 < ani->ofdm_phy_err_base) { + AR_WRITE(sc, AR_PHY_ERR_1, ani->ofdm_phy_err_base); + AR_WRITE(sc, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); + } + if (phy2 < ani->cck_phy_err_base) { + AR_WRITE(sc, AR_PHY_ERR_2, ani->cck_phy_err_base); + AR_WRITE(sc, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); + } + if (phy1 < ani->ofdm_phy_err_base || phy2 < ani->cck_phy_err_base) { + AR_WRITE_BARRIER(sc); + return; + } + ani->ofdm_phy_err_count = phy1 - ani->ofdm_phy_err_base; + ani->cck_phy_err_count = phy2 - ani->cck_phy_err_base; + + if (ani->listen_time > 5 * ATHN_ANI_PERIOD) { + /* Check to see if we need to lower immunity. */ + if (ani->ofdm_phy_err_count <= + ani->listen_time * ani->ofdm_trig_low / 1000 && + ani->cck_phy_err_count <= + ani->listen_time * ani->cck_trig_low / 1000) + athn_ani_lower_immunity(sc); + athn_ani_restart(sc); + + } else if (ani->listen_time > ATHN_ANI_PERIOD) { + /* Check to see if we need to raise immunity. */ + if (ani->ofdm_phy_err_count > + ani->listen_time * ani->ofdm_trig_high / 1000) { + athn_ani_ofdm_err_trigger(sc); + athn_ani_restart(sc); + } else if (ani->cck_phy_err_count > + ani->listen_time * ani->cck_trig_high / 1000) { + athn_ani_cck_err_trigger(sc); + athn_ani_restart(sc); + } + } +} + +uint8_t +athn_chan2fbin(struct ieee80211_channel *c) +{ + if (IEEE80211_IS_CHAN_2GHZ(c)) + return (c->ic_freq - 2300); + else + return ((c->ic_freq - 4800) / 5); +} + +int +athn_interpolate(int x, int x1, int y1, int x2, int y2) +{ + if (x1 == x2) /* Prevents division by zero. */ + return (y1); + /* Linear interpolation. */ + return (y1 + ((x - x1) * (y2 - y1)) / (x2 - x1)); +} + +void +athn_get_pier_ival(uint8_t fbin, const uint8_t *pierfreq, int npiers, + int *lo, int *hi) +{ + int i; + + for (i = 0; i < npiers; i++) + if (pierfreq[i] == AR_BCHAN_UNUSED || + pierfreq[i] > fbin) + break; + *hi = i; + *lo = *hi - 1; + if (*lo == -1) + *lo = *hi; + else if (*hi == npiers || pierfreq[*hi] == AR_BCHAN_UNUSED) + *hi = *lo; +} + +void +athn_init_dma(struct athn_softc *sc) +{ + uint32_t reg; + + if (!AR_SREV_9380_10_OR_LATER(sc)) { + /* Set AHB not to do cacheline prefetches. */ + AR_SETBITS(sc, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN); + } + reg = AR_READ(sc, AR_TXCFG); + /* Let MAC DMA reads be in 128-byte chunks. */ + reg = RW(reg, AR_TXCFG_DMASZ, AR_DMASZ_128B); + + /* Set initial Tx trigger level. */ + if (AR_SREV_9285(sc) || AR_SREV_9271(sc)) + reg = RW(reg, AR_TXCFG_FTRIG, AR_TXCFG_FTRIG_256B); + else if (!AR_SREV_9380_10_OR_LATER(sc)) + reg = RW(reg, AR_TXCFG_FTRIG, AR_TXCFG_FTRIG_512B); + AR_WRITE(sc, AR_TXCFG, reg); + + /* Let MAC DMA writes be in 128-byte chunks. */ + reg = AR_READ(sc, AR_RXCFG); + reg = RW(reg, AR_RXCFG_DMASZ, AR_DMASZ_128B); + AR_WRITE(sc, AR_RXCFG, reg); + + /* Setup Rx FIFO threshold to hold off Tx activities. */ + AR_WRITE(sc, AR_RXFIFO_CFG, 512); + + /* Reduce the number of entries in PCU TXBUF to avoid wrap around. */ + if (AR_SREV_9285(sc)) { + AR_WRITE(sc, AR_PCU_TXBUF_CTRL, + AR9285_PCU_TXBUF_CTRL_USABLE_SIZE); + } else if (!AR_SREV_9271(sc)) { + AR_WRITE(sc, AR_PCU_TXBUF_CTRL, + AR_PCU_TXBUF_CTRL_USABLE_SIZE); + } + AR_WRITE_BARRIER(sc); +} + +void +athn_inc_tx_trigger_level(struct athn_softc *sc) +{ + uint32_t reg, ftrig; + + reg = AR_READ(sc, AR_TXCFG); + ftrig = MS(reg, AR_TXCFG_FTRIG); + /* + * NB: The AR9285 and all single-stream parts have an issue that + * limits the size of the PCU Tx FIFO to 2KB instead of 4KB. + */ + if (ftrig == ((AR_SREV_9285(sc) || AR_SREV_9271(sc)) ? 0x1f : 0x3f)) + return; /* Already at max. */ + reg = RW(reg, AR_TXCFG_FTRIG, ftrig + 1); + AR_WRITE(sc, AR_TXCFG, reg); + AR_WRITE_BARRIER(sc); +} + +int +athn_stop_rx_dma(struct athn_softc *sc) +{ + int ntries; + + AR_WRITE(sc, AR_CR, AR_CR_RXD); + /* Wait for Rx enable bit to go low. */ + for (ntries = 0; ntries < 100; ntries++) { + if (!(AR_READ(sc, AR_CR) & AR_CR_RXE)) + return (0); + DELAY(100); + } + DPRINTF(("Rx DMA failed to stop\n")); + return (ETIMEDOUT); +} + +int +athn_rx_abort(struct athn_softc *sc) +{ + int ntries; + + AR_SETBITS(sc, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT); + for (ntries = 0; ntries < 1000; ntries++) { + if (MS(AR_READ(sc, AR_OBS_BUS_1), AR_OBS_BUS_1_RX_STATE) == 0) + return (0); + DELAY(10); + } + DPRINTF(("Rx failed to go idle in 10ms\n")); + AR_CLRBITS(sc, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT); + AR_WRITE_BARRIER(sc); + return (ETIMEDOUT); +} + +void +athn_tx_reclaim(struct athn_softc *sc, int qid) +{ + struct athn_txq *txq = &sc->txq[qid]; + struct athn_tx_buf *bf; + + /* Reclaim all buffers queued in the specified Tx queue. */ + /* NB: Tx DMA must be stopped. */ + while ((bf = SIMPLEQ_FIRST(&txq->head)) != NULL) { + SIMPLEQ_REMOVE_HEAD(&txq->head, bf_list); + + // TODO incomplete definition of type 'struct bus_dmamap' + // bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, + // bf->bf_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); + // bus_dmamap_unload(sc->sc_dmat, bf->bf_map); + m_freem(bf->bf_m); + bf->bf_m = NULL; + bf->bf_ni = NULL; /* Nodes already freed! */ + + /* Link Tx buffer back to global free list. */ + SIMPLEQ_INSERT_TAIL(&sc->txbufs, bf, bf_list); + } +} + +int +athn_tx_pending(struct athn_softc *sc, int qid) +{ + return (MS(AR_READ(sc, AR_QSTS(qid)), AR_Q_STS_PEND_FR_CNT) != 0 || + (AR_READ(sc, AR_Q_TXE) & (1 << qid)) != 0); +} + +void +athn_stop_tx_dma(struct athn_softc *sc, int qid) +{ + uint32_t tsflo; + int ntries, i; + + AR_WRITE(sc, AR_Q_TXD, 1 << qid); + for (ntries = 0; ntries < 40; ntries++) { + if (!athn_tx_pending(sc, qid)) + break; + DELAY(100); + } + if (ntries == 40) { + for (i = 0; i < 2; i++) { + tsflo = AR_READ(sc, AR_TSF_L32) / 1024; + AR_WRITE(sc, AR_QUIET2, + SM(AR_QUIET2_QUIET_DUR, 10)); + AR_WRITE(sc, AR_QUIET_PERIOD, 100); + AR_WRITE(sc, AR_NEXT_QUIET_TIMER, tsflo); + AR_SETBITS(sc, AR_TIMER_MODE, AR_QUIET_TIMER_EN); + if (AR_READ(sc, AR_TSF_L32) / 1024 == tsflo) + break; + } + AR_SETBITS(sc, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); + AR_WRITE_BARRIER(sc); + DELAY(200); + AR_CLRBITS(sc, AR_TIMER_MODE, AR_QUIET_TIMER_EN); + AR_WRITE_BARRIER(sc); + + for (ntries = 0; ntries < 40; ntries++) { + if (!athn_tx_pending(sc, qid)) + break; + DELAY(100); + } + + AR_CLRBITS(sc, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); + } + AR_WRITE(sc, AR_Q_TXD, 0); + AR_WRITE_BARRIER(sc); +} + +int +athn_txtime(struct athn_softc *sc, int len, int ridx, u_int flags) +{ + __attribute__((unused)) struct ieee80211com *ic = &sc->sc_ic; +#define divround(a, b) (((a) + (b) - 1) / (b)) + int txtime; + + if (athn_rates[ridx].hwrate & 0x80) { /* MCS */ + /* Assumes a 20MHz channel, HT-mixed frame format, no STBC. */ + txtime = 8 + 8 + 4 + 4 + 4 * 4 + 8 /* HT PLCP */ + + 4 * ((8 * len + 16 + 6) / (athn_rates[ridx].rate * 2)); + // TODO no member named 'ic_bss' in 'struct ieee80211com' + // if (IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan)) + // txtime += 6; /* aSignalExtension */ + } else if (athn_rates[ridx].phy == IEEE80211_T_OFDM) { + txtime = divround(8 + 4 * len + 3, athn_rates[ridx].rate); + /* SIFS is 10us for 11g but Signal Extension adds 6us. */ + txtime = 16 + 4 + 4 * txtime + 16; + } else { + txtime = divround(16 * len, athn_rates[ridx].rate); + if (ridx != ATHN_RIDX_CCK1 && (flags & IEEE80211_F_SHPREAMBLE)) + txtime += 72 + 24; + else + txtime += 144 + 48; + txtime += 10; /* 10us SIFS. */ + } + return (txtime); +#undef divround +} + +void +athn_init_tx_queues(struct athn_softc *sc) +{ + int qid; + + for (qid = 0; qid < ATHN_QID_COUNT; qid++) { + SIMPLEQ_INIT(&sc->txq[qid].head); + sc->txq[qid].lastds = NULL; + sc->txq[qid].wait = NULL; + sc->txq[qid].queued = 0; + + AR_WRITE(sc, AR_DRETRY_LIMIT(qid), + SM(AR_D_RETRY_LIMIT_STA_SH, 32) | + SM(AR_D_RETRY_LIMIT_STA_LG, 32) | + SM(AR_D_RETRY_LIMIT_FR_SH, 10)); + AR_WRITE(sc, AR_QMISC(qid), + AR_Q_MISC_DCU_EARLY_TERM_REQ); + AR_WRITE(sc, AR_DMISC(qid), + SM(AR_D_MISC_BKOFF_THRESH, 2) | + AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN); + } + + /* Init beacon queue. */ + AR_SETBITS(sc, AR_QMISC(ATHN_QID_BEACON), + AR_Q_MISC_FSP_DBA_GATED | AR_Q_MISC_BEACON_USE | + AR_Q_MISC_CBR_INCR_DIS1); + AR_SETBITS(sc, AR_DMISC(ATHN_QID_BEACON), + SM(AR_D_MISC_ARB_LOCKOUT_CNTRL, + AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL) | + AR_D_MISC_BEACON_USE | + AR_D_MISC_POST_FR_BKOFF_DIS); + AR_WRITE(sc, AR_DLCL_IFS(ATHN_QID_BEACON), + SM(AR_D_LCL_IFS_CWMIN, 0) | + SM(AR_D_LCL_IFS_CWMAX, 0) | + SM(AR_D_LCL_IFS_AIFS, 1)); + + /* Init CAB (Content After Beacon) queue. */ + AR_SETBITS(sc, AR_QMISC(ATHN_QID_CAB), + AR_Q_MISC_FSP_DBA_GATED | AR_Q_MISC_CBR_INCR_DIS1 | + AR_Q_MISC_CBR_INCR_DIS0); + AR_SETBITS(sc, AR_DMISC(ATHN_QID_CAB), + SM(AR_D_MISC_ARB_LOCKOUT_CNTRL, + AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL)); + + /* Init PS-Poll queue. */ + AR_SETBITS(sc, AR_QMISC(ATHN_QID_PSPOLL), + AR_Q_MISC_CBR_INCR_DIS1); + + /* Init UAPSD queue. */ + AR_SETBITS(sc, AR_DMISC(ATHN_QID_UAPSD), + AR_D_MISC_POST_FR_BKOFF_DIS); + + if (AR_SREV_9380_10_OR_LATER(sc)) { + /* Enable MAC descriptor CRC check. */ + AR_WRITE(sc, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN); + } + /* Enable DESC interrupts for all Tx queues. */ + AR_WRITE(sc, AR_IMR_S0, 0x00ff0000); + /* Enable EOL interrupts for all Tx queues except UAPSD. */ + AR_WRITE(sc, AR_IMR_S1, 0x00df0000); + AR_WRITE_BARRIER(sc); +} + +void +athn_set_sta_timers(struct athn_softc *sc) +{ + __attribute__((unused)) struct ieee80211com *ic = &sc->sc_ic; + uint32_t tsfhi, tsflo, tsftu, reg; + uint32_t intval = 0, next_tbtt, next_dtim; + __attribute__((unused)) int dtim_period, dtim_count = 0, rem_dtim_count = 0; + + tsfhi = AR_READ(sc, AR_TSF_U32); + tsflo = AR_READ(sc, AR_TSF_L32); + tsftu = AR_TSF_TO_TU(tsfhi, tsflo) + AR_FUDGE; + + /* Beacon interval in TU. */ + // TODO no member named 'ic_bss' in 'struct ieee80211com' + // intval = ic->ic_bss->ni_intval; + + next_tbtt = roundup(tsftu, intval); +#ifdef notyet + dtim_period = ic->ic_dtim_period; + if (dtim_period <= 0) +#endif + dtim_period = 1; /* Assume all TIMs are DTIMs. */ + +#ifdef notyet + dtim_count = ic->ic_dtim_count; + if (dtim_count >= dtim_period) /* Should not happen. */ +#endif + dtim_count = 0; /* Assume last TIM was a DTIM. */ + + /* Compute number of remaining TIMs until next DTIM. */ + rem_dtim_count = 0; /* XXX */ + next_dtim = next_tbtt + rem_dtim_count * intval; + + AR_WRITE(sc, AR_NEXT_TBTT_TIMER, next_tbtt * IEEE80211_DUR_TU); + AR_WRITE(sc, AR_BEACON_PERIOD, intval * IEEE80211_DUR_TU); + AR_WRITE(sc, AR_DMA_BEACON_PERIOD, intval * IEEE80211_DUR_TU); + + /* + * Set the number of consecutive beacons to miss before raising + * a BMISS interrupt to 10. + */ + reg = AR_READ(sc, AR_RSSI_THR); + reg = RW(reg, AR_RSSI_THR_BM_THR, 10); + AR_WRITE(sc, AR_RSSI_THR, reg); + + AR_WRITE(sc, AR_NEXT_DTIM, + (next_dtim - AR_SLEEP_SLOP) * IEEE80211_DUR_TU); + AR_WRITE(sc, AR_NEXT_TIM, + (next_tbtt - AR_SLEEP_SLOP) * IEEE80211_DUR_TU); + + /* CAB timeout is in 1/8 TU. */ + AR_WRITE(sc, AR_SLEEP1, + SM(AR_SLEEP1_CAB_TIMEOUT, AR_CAB_TIMEOUT_VAL * 8) | + AR_SLEEP1_ASSUME_DTIM); + AR_WRITE(sc, AR_SLEEP2, + SM(AR_SLEEP2_BEACON_TIMEOUT, AR_MIN_BEACON_TIMEOUT_VAL)); + + AR_WRITE(sc, AR_TIM_PERIOD, intval * IEEE80211_DUR_TU); + AR_WRITE(sc, AR_DTIM_PERIOD, dtim_period * intval * IEEE80211_DUR_TU); + + AR_SETBITS(sc, AR_TIMER_MODE, + AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN | AR_DTIM_TIMER_EN); + + /* Set TSF out-of-range threshold (fixed at 16k us). */ + AR_WRITE(sc, AR_TSFOOR_THRESHOLD, 0x4240); + + AR_WRITE_BARRIER(sc); +} + +#ifndef IEEE80211_STA_ONLY +void +athn_set_hostap_timers(struct athn_softc *sc) +{ + __attribute__((unused)) struct ieee80211com *ic = &sc->sc_ic; + uint32_t intval = 0, next_tbtt; + + /* Beacon interval in TU. */ + // TODO no member named 'ic_bss' in 'struct ieee80211com' + // intval = ic->ic_bss->ni_intval; + next_tbtt = intval; + + AR_WRITE(sc, AR_NEXT_TBTT_TIMER, next_tbtt * IEEE80211_DUR_TU); + AR_WRITE(sc, AR_NEXT_DMA_BEACON_ALERT, + (next_tbtt - AR_BEACON_DMA_DELAY) * IEEE80211_DUR_TU); + AR_WRITE(sc, AR_NEXT_CFP, + (next_tbtt - AR_SWBA_DELAY) * IEEE80211_DUR_TU); + + AR_WRITE(sc, AR_BEACON_PERIOD, intval * IEEE80211_DUR_TU); + AR_WRITE(sc, AR_DMA_BEACON_PERIOD, intval * IEEE80211_DUR_TU); + AR_WRITE(sc, AR_SWBA_PERIOD, intval * IEEE80211_DUR_TU); + AR_WRITE(sc, AR_NDP_PERIOD, intval * IEEE80211_DUR_TU); + + AR_WRITE(sc, AR_TIMER_MODE, + AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN); + + AR_WRITE_BARRIER(sc); +} +#endif + +void +athn_set_opmode(struct athn_softc *sc) +{ + uint32_t reg; + + switch (sc->sc_ic.ic_opmode) { +#ifndef IEEE80211_STA_ONLY + case IEEE80211_M_HOSTAP: + reg = AR_READ(sc, AR_STA_ID1); + reg &= ~AR_STA_ID1_ADHOC; + reg |= AR_STA_ID1_STA_AP | AR_STA_ID1_KSRCH_MODE; + AR_WRITE(sc, AR_STA_ID1, reg); + + AR_CLRBITS(sc, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); + break; + case IEEE80211_M_IBSS: + case IEEE80211_M_AHDEMO: + reg = AR_READ(sc, AR_STA_ID1); + reg &= ~AR_STA_ID1_STA_AP; + reg |= AR_STA_ID1_ADHOC | AR_STA_ID1_KSRCH_MODE; + AR_WRITE(sc, AR_STA_ID1, reg); + + AR_SETBITS(sc, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); + break; +#endif + default: + reg = AR_READ(sc, AR_STA_ID1); + reg &= ~(AR_STA_ID1_ADHOC | AR_STA_ID1_STA_AP); + reg |= AR_STA_ID1_KSRCH_MODE; + AR_WRITE(sc, AR_STA_ID1, reg); + break; + } + AR_WRITE_BARRIER(sc); +} + +void +athn_set_bss(struct athn_softc *sc, struct ieee80211_node *ni) +{ + const uint8_t *bssid = ni->ni_bssid; + + AR_WRITE(sc, AR_BSS_ID0, LE_READ_4(&bssid[0])); + AR_WRITE(sc, AR_BSS_ID1, LE_READ_2(&bssid[4]) | + SM(AR_BSS_ID1_AID, IEEE80211_AID(ni->ni_associd))); + AR_WRITE_BARRIER(sc); +} + +void +athn_enable_interrupts(struct athn_softc *sc) +{ + uint32_t mask2; + + athn_disable_interrupts(sc); /* XXX */ + + AR_WRITE(sc, AR_IMR, sc->imask); + + mask2 = AR_READ(sc, AR_IMR_S2); + mask2 &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC | + AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | AR_IMR_S2_TSFOOR); + mask2 |= AR_IMR_S2_GTT | AR_IMR_S2_CST; + AR_WRITE(sc, AR_IMR_S2, mask2); + + AR_CLRBITS(sc, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); + + AR_WRITE(sc, AR_IER, AR_IER_ENABLE); + + AR_WRITE(sc, AR_INTR_ASYNC_ENABLE, AR_INTR_MAC_IRQ); + AR_WRITE(sc, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ); + + AR_WRITE(sc, AR_INTR_SYNC_ENABLE, sc->isync); + AR_WRITE(sc, AR_INTR_SYNC_MASK, sc->isync); + AR_WRITE_BARRIER(sc); +} + +void +athn_disable_interrupts(struct athn_softc *sc) +{ + AR_WRITE(sc, AR_IER, 0); + (void)AR_READ(sc, AR_IER); + + AR_WRITE(sc, AR_INTR_ASYNC_ENABLE, 0); + (void)AR_READ(sc, AR_INTR_ASYNC_ENABLE); + + AR_WRITE(sc, AR_INTR_SYNC_ENABLE, 0); + (void)AR_READ(sc, AR_INTR_SYNC_ENABLE); + + AR_WRITE(sc, AR_IMR, 0); + + AR_CLRBITS(sc, AR_IMR_S2, AR_IMR_S2_TIM | AR_IMR_S2_DTIM | + AR_IMR_S2_DTIMSYNC | AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | + AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST); + + AR_CLRBITS(sc, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); + AR_WRITE_BARRIER(sc); +} + +void +athn_init_qos(struct athn_softc *sc) +{ + /* Initialize QoS settings. */ + AR_WRITE(sc, AR_MIC_QOS_CONTROL, 0x100aa); + AR_WRITE(sc, AR_MIC_QOS_SELECT, 0x3210); + AR_WRITE(sc, AR_QOS_NO_ACK, + SM(AR_QOS_NO_ACK_TWO_BIT, 2) | + SM(AR_QOS_NO_ACK_BIT_OFF, 5) | + SM(AR_QOS_NO_ACK_BYTE_OFF, 0)); + AR_WRITE(sc, AR_TXOP_X, AR_TXOP_X_VAL); + /* Initialize TXOP for all TIDs. */ + AR_WRITE(sc, AR_TXOP_0_3, 0xffffffff); + AR_WRITE(sc, AR_TXOP_4_7, 0xffffffff); + AR_WRITE(sc, AR_TXOP_8_11, 0xffffffff); + AR_WRITE(sc, AR_TXOP_12_15, 0xffffffff); + AR_WRITE_BARRIER(sc); +} + +int +athn_hw_reset(struct athn_softc *sc, struct ieee80211_channel *c, + struct ieee80211_channel *extc, int init) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct athn_ops *ops = &sc->ops; + uint32_t reg, def_ant, sta_id1, cfg_led, tsflo, tsfhi; + int i, error; + + /* XXX not if already awake */ + if ((error = athn_set_power_awake(sc)) != 0) { + device_printf(sc->sc_dev, "%s: could not wakeup chip\n", __func__); + return (error); + } + + /* Preserve the antenna on a channel switch. */ + if ((def_ant = AR_READ(sc, AR_DEF_ANTENNA)) == 0) + def_ant = 1; + /* Preserve other registers. */ + sta_id1 = AR_READ(sc, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; + cfg_led = AR_READ(sc, AR_CFG_LED) & (AR_CFG_LED_ASSOC_CTL_M | + AR_CFG_LED_MODE_SEL_M | AR_CFG_LED_BLINK_THRESH_SEL_M | + AR_CFG_LED_BLINK_SLOW); + + /* Mark PHY as inactive. */ + ops->disable_phy(sc); + + if (init && AR_SREV_9271(sc)) { + AR_WRITE(sc, AR9271_RESET_POWER_DOWN_CONTROL, + AR9271_RADIO_RF_RST); + DELAY(50); + } + if (AR_SREV_9280(sc) && (sc->flags & ATHN_FLAG_OLPC)) { + /* Save TSF before it gets cleared. */ + tsfhi = AR_READ(sc, AR_TSF_U32); + tsflo = AR_READ(sc, AR_TSF_L32); + + /* NB: RTC reset clears TSF. */ + error = athn_reset_power_on(sc); + } else + error = athn_reset(sc, 0); + if (error != 0) { + device_printf(sc->sc_dev, "%s: could not reset chip (error=%d)\n", __func__, error); + return (error); + } + + /* XXX not if already awake */ + if ((error = athn_set_power_awake(sc)) != 0) { + device_printf(sc->sc_dev, "%s: could not wakeup chip", __func__); + return (error); + } + + athn_init_pll(sc, c); + ops->set_rf_mode(sc, c); + + if (sc->flags & ATHN_FLAG_RFSILENT) { + /* Check that the radio is not disabled by hardware switch. */ + reg = ops->gpio_read(sc, sc->rfsilent_pin); + if (sc->flags & ATHN_FLAG_RFSILENT_REVERSED) + reg = !reg; + if (!reg) { + device_printf(sc->sc_dev, "%s: radio is disabled by hardware switch\n", __func__); + return (EPERM); + } + } + if (init && AR_SREV_9271(sc)) { + AR_WRITE(sc, AR9271_RESET_POWER_DOWN_CONTROL, + AR9271_GATE_MAC_CTL); + DELAY(50); + } + if (AR_SREV_9280(sc) && (sc->flags & ATHN_FLAG_OLPC)) { + /* Restore TSF if it got cleared. */ + AR_WRITE(sc, AR_TSF_L32, tsflo); + AR_WRITE(sc, AR_TSF_U32, tsfhi); + } + + if (AR_SREV_9280_10_OR_LATER(sc)) + AR_SETBITS(sc, sc->gpio_input_en_off, AR_GPIO_JTAG_DISABLE); + + /* Write init values to hardware. */ + ops->hw_init(sc, c, extc); + + /* + * Only >=AR9280 2.0 parts are capable of encrypting unicast + * management frames using CCMP. + */ + if (AR_SREV_9280_20_OR_LATER(sc)) { + reg = AR_READ(sc, AR_AES_MUTE_MASK1); + /* Do not mask the subtype field in management frames. */ + reg = RW(reg, AR_AES_MUTE_MASK1_FC0_MGMT, 0xff); + reg = RW(reg, AR_AES_MUTE_MASK1_FC1_MGMT, + ~(IEEE80211_FC1_RETRY | IEEE80211_FC1_PWR_MGT | + IEEE80211_FC1_MORE_DATA)); + AR_WRITE(sc, AR_AES_MUTE_MASK1, reg); + } else if (AR_SREV_9160_10_OR_LATER(sc)) { + /* Disable hardware crypto for management frames. */ + AR_CLRBITS(sc, AR_PCU_MISC_MODE2, + AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE); + AR_SETBITS(sc, AR_PCU_MISC_MODE2, + AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT); + } + + if (ic->ic_curmode != IEEE80211_MODE_11B) + ops->set_delta_slope(sc, c, extc); + + ops->spur_mitigate(sc, c, extc); + ops->init_from_rom(sc, c, extc); + + /* XXX */ + AR_WRITE(sc, AR_STA_ID0, LE_READ_4(&ic->ic_macaddr[0])); + AR_WRITE(sc, AR_STA_ID1, LE_READ_2(&ic->ic_macaddr[4]) | + sta_id1 | AR_STA_ID1_RTS_USE_DEF | AR_STA_ID1_CRPT_MIC_ENABLE); + + athn_set_opmode(sc); + + AR_WRITE(sc, AR_BSSMSKL, 0xffffffff); + AR_WRITE(sc, AR_BSSMSKU, 0xffff); + + /* Restore previous antenna. */ + AR_WRITE(sc, AR_DEF_ANTENNA, def_ant); + + AR_WRITE(sc, AR_BSS_ID0, 0); + AR_WRITE(sc, AR_BSS_ID1, 0); + + AR_WRITE(sc, AR_ISR, 0xffffffff); + + AR_WRITE(sc, AR_RSSI_THR, SM(AR_RSSI_THR_BM_THR, 7)); + + if ((error = ops->set_synth(sc, c, extc)) != 0) { + // TOTO missing field 'dv_xname' in 'struct device' + // printf("%s: could not set channel\n", sc->sc_dev.dv_xname); + device_printf(sc->sc_dev, "%s: ould not set channel\n", __func__); + return (error); + } + sc->curchan = c; + sc->curchanext = extc; + + for (i = 0; i < AR_NUM_DCU; i++) + AR_WRITE(sc, AR_DQCUMASK(i), 1 << i); + + athn_init_tx_queues(sc); + + /* Initialize interrupt mask. */ + sc->imask = + AR_IMR_TXDESC | AR_IMR_TXEOL | + AR_IMR_RXERR | AR_IMR_RXEOL | AR_IMR_RXORN | + AR_IMR_RXMINTR | AR_IMR_RXINTM | + AR_IMR_GENTMR | AR_IMR_BCNMISC; + if (AR_SREV_9380_10_OR_LATER(sc)) + sc->imask |= AR_IMR_RXERR | AR_IMR_HP_RXOK; +#ifndef IEEE80211_STA_ONLY + if (0 && ic->ic_opmode == IEEE80211_M_HOSTAP) + sc->imask |= AR_IMR_MIB; +#endif + AR_WRITE(sc, AR_IMR, sc->imask); + AR_SETBITS(sc, AR_IMR_S2, AR_IMR_S2_GTT); + AR_WRITE(sc, AR_INTR_SYNC_CAUSE, 0xffffffff); + sc->isync = AR_INTR_SYNC_DEFAULT; + if (sc->flags & ATHN_FLAG_RFSILENT) + sc->isync |= AR_INTR_SYNC_GPIO_PIN(sc->rfsilent_pin); + AR_WRITE(sc, AR_INTR_SYNC_ENABLE, sc->isync); + AR_WRITE(sc, AR_INTR_SYNC_MASK, 0); + if (AR_SREV_9380_10_OR_LATER(sc)) { + AR_WRITE(sc, AR_INTR_PRIO_ASYNC_ENABLE, 0); + AR_WRITE(sc, AR_INTR_PRIO_ASYNC_MASK, 0); + AR_WRITE(sc, AR_INTR_PRIO_SYNC_ENABLE, 0); + AR_WRITE(sc, AR_INTR_PRIO_SYNC_MASK, 0); + } + + athn_init_qos(sc); + + AR_SETBITS(sc, AR_PCU_MISC, AR_PCU_MIC_NEW_LOC_ENA); + + athn_setsifs(sc); + athn_updateslot(ic); + athn_setclockrate(sc); + + /* Disable sequence number generation in hardware. */ + AR_SETBITS(sc, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM); + + athn_init_dma(sc); + + /* Program observation bus to see MAC interrupts. */ + AR_WRITE(sc, sc->obs_off, 8); + + /* Setup Rx interrupt mitigation. */ + AR_WRITE(sc, AR_RIMT, SM(AR_RIMT_FIRST, 2000) | SM(AR_RIMT_LAST, 500)); + + /* Setup Tx interrupt mitigation. */ + AR_WRITE(sc, AR_TIMT, SM(AR_TIMT_FIRST, 2000) | SM(AR_TIMT_LAST, 500)); + + /* Set maximum interrupt rate threshold (in micro seconds). */ + AR_WRITE(sc, AR_MIRT, SM(AR_MIRT_RATE_THRES, 2000)); + + ops->init_baseband(sc); + + if ((error = athn_init_calib(sc, c, extc)) != 0) { + device_printf(sc->sc_dev, "%s: could not initialize calibration\n", __func__); + return (error); + } + + ops->set_rxchains(sc); + + AR_WRITE(sc, AR_CFG_LED, cfg_led | AR_CFG_SCLK_32KHZ); + + if (sc->flags & ATHN_FLAG_USB) { + if (AR_SREV_9271(sc)) + AR_WRITE(sc, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB); + else + AR_WRITE(sc, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); + } +#if BYTE_ORDER == BIG_ENDIAN + else { + /* Default is LE, turn on swapping for BE. */ + AR_WRITE(sc, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); + } +#endif + AR_WRITE_BARRIER(sc); + + return (0); +} + +struct ieee80211_node * +athn_node_alloc(struct ieee80211com *ic) +{ + struct athn_node *an; + + // TODO missing macro in ieee80211_var.h + #define IEEE80211_F_HTON 0x02000000 /* CONF: HT enabled */ +#if OpenBSD_IEEE80211_API + an = malloc(sizeof(struct athn_node), M_DEVBUF, M_NOWAIT | M_ZERO); + if (an && (ic->ic_flags & IEEE80211_F_HTON)) + ieee80211_ra_node_init(&an->rn); + return (struct ieee80211_node *)an; +#endif + return NULL; +} + +void +athn_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew) +{ + struct athn_softc *sc = ic->ic_softc; + struct athn_node *an = (void *)ni; + struct ieee80211_rateset *rs = &ni->ni_rates; + uint8_t rate; + int ridx, i, j; + + // TODO implicit declaration of function 'ieee80211_amrr_node_init' +#if OpenBSD_IEEE80211_API + if ((ni->ni_flags & IEEE80211_NODE_HT) == 0) + ieee80211_amrr_node_init(&sc->amrr, &an->amn); + else if (ic->ic_opmode == IEEE80211_M_STA) + ieee80211_ra_node_init(&an->rn); +#endif + + /* Start at lowest available bit-rate, AMRR will raise. */ + ni->ni_txrate = 0; + + for (i = 0; i < rs->rs_nrates; i++) { + rate = rs->rs_rates[i] & IEEE80211_RATE_VAL; + + /* Map 802.11 rate to HW rate index. */ + for (ridx = 0; ridx <= ATHN_RIDX_MAX; ridx++) + if (athn_rates[ridx].rate == rate) + break; + an->ridx[i] = ridx; + DPRINTFN(2, ("rate %d index %d\n", rate, ridx)); + + /* Compute fallback rate for retries. */ + an->fallback[i] = i; + for (j = i - 1; j >= 0; j--) { + if (athn_rates[an->ridx[j]].phy == + athn_rates[an->ridx[i]].phy) { + an->fallback[i] = j; + break; + } + } + DPRINTFN(2, ("%d fallbacks to %d\n", i, an->fallback[i])); + } + + /* In 11n mode, start at lowest available bit-rate, MiRA will raise. */ + // TODO no member named 'ni_txmcs' in 'struct ieee80211_node' + // ni->ni_txmcs = 0; + + for (i = 0; i <= ATHN_MCS_MAX; i++) { + /* Map MCS index to HW rate index. */ + ridx = ATHN_NUM_LEGACY_RATES + i; + an->ridx[ridx] = ATHN_RIDX_MCS0 + i; + + DPRINTFN(2, ("mcs %d index %d ", i, ridx)); + /* Compute fallback rate for retries. */ + if (i == 0 || i == 8) { + /* MCS 0 and 8 fall back to the lowest legacy rate. */ + if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) + an->fallback[ridx] = ATHN_RIDX_OFDM6; + else + an->fallback[ridx] = ATHN_RIDX_CCK1; + } else { + /* Other MCS fall back to next supported lower MCS. */ + an->fallback[ridx] = ATHN_NUM_LEGACY_RATES + i; + for (j = i - 1; j >= 0; j--) { +#if OpenBSD_IEEE80211_API + if (!isset(ni->ni_rxmcs, j)) + continue; +#endif + an->fallback[ridx] = ATHN_NUM_LEGACY_RATES + j; + break; + } + } + DPRINTFN(2, (" fallback to %d\n", an->fallback[ridx])); + } +} + +int +athn_media_change(struct ifnet *ifp) +{ + struct athn_softc *sc = ifp->if_softc; + __attribute__((unused)) struct ieee80211com *ic = &sc->sc_ic; + uint8_t rate, ridx; + int error; + + error = ieee80211_media_change(ifp); + if (error != ENETRESET) + return (error); +#if OpenBSD_IEEE80211_API + if (ic->ic_fixed_rate != -1) { + rate = ic->ic_sup_rates[ic->ic_curmode]. + rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; + /* Map 802.11 rate to HW rate index. */ + for (ridx = 0; ridx <= ATHN_RIDX_MAX; ridx++) + if (athn_rates[ridx].rate == rate) + break; + sc->fixed_ridx = ridx; + } +#endif + if ((ifp->if_flags & (IFF_UP | IFF_DRV_RUNNING)) == + (IFF_UP | IFF_DRV_RUNNING)) { + athn_stop(ifp, 0); + error = athn_init(ifp); + } + return (error); +} + +void +athn_next_scan(void *arg) +{ + struct athn_softc *sc = arg; + __attribute__((unused)) struct ieee80211com *ic = &sc->sc_ic; + int s; + + s = splnet(); +#if OpenBSD_IEEE80211_API + if (ic->ic_state == IEEE80211_S_SCAN) + ieee80211_next_scan(&ic->ic_if); +#endif + splx(s); +} + +// Not needed +int +athn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) +{ +#if OpenBSD_IEEE80211_API + struct ifnet *ifp = &ic->ic_if; + struct athn_softc *sc = ifp->if_softc; + uint32_t reg; + int error = 0; + + timeout_del(&sc->calib_to); + + switch (nstate) { + case IEEE80211_S_INIT: + athn_set_led(sc, 0); + break; + case IEEE80211_S_SCAN: + /* Make the LED blink while scanning. */ + athn_set_led(sc, !sc->led_state); + // TODO no member named 'ic_bss' in 'struct ieee80211com' + error = athn_switch_chan(sc, ic->ic_bss->ni_chan, NULL); + if (error != 0) + return (error); + timeout_add_msec(&sc->scan_to, 200); + break; + case IEEE80211_S_AUTH: + athn_set_led(sc, 0); + // TODO no member named 'ic_bss' in 'struct ieee80211com' + error = athn_switch_chan(sc, ic->ic_bss->ni_chan, NULL); + if (error != 0) + return (error); + break; + case IEEE80211_S_ASSOC: + break; + case IEEE80211_S_RUN: + athn_set_led(sc, 1); +#ifndef IEEE80211_STA_ONLY + if (ic->ic_opmode == IEEE80211_M_HOSTAP) { + error = athn_switch_chan(sc, ic->ic_bss->ni_chan, NULL); + if (error != 0) + return (error); + } else +#endif + if (ic->ic_opmode == IEEE80211_M_MONITOR) { + error = athn_switch_chan(sc, ic->ic_ibss_chan, NULL); + if (error != 0) + return (error); + break; + } + + /* Fake a join to initialize the Tx rate. */ + // TODO no member named 'ic_bss' in 'struct ieee80211com' + athn_newassoc(ic, ic->ic_bss, 1); + + athn_set_bss(sc, ic->ic_bss); + athn_disable_interrupts(sc); +#ifndef IEEE80211_STA_ONLY + if (ic->ic_opmode == IEEE80211_M_HOSTAP) { + athn_set_hostap_timers(sc); + /* Enable software beacon alert interrupts. */ + sc->imask |= AR_IMR_SWBA; + } else +#endif + { + athn_set_sta_timers(sc); + /* Enable beacon miss interrupts. */ + sc->imask |= AR_IMR_BMISS; + + /* Stop receiving beacons from other BSS. */ + reg = AR_READ(sc, AR_RX_FILTER); + reg = (reg & ~AR_RX_FILTER_BEACON) | + AR_RX_FILTER_MYBEACON; + AR_WRITE(sc, AR_RX_FILTER, reg); + AR_WRITE_BARRIER(sc); + } + athn_enable_interrupts(sc); + + if (sc->sup_calib_mask != 0) { + memset(&sc->calib, 0, sizeof(sc->calib)); + sc->cur_calib_mask = sc->sup_calib_mask; + sc->ops.do_calib(sc); + } + /* XXX Start ANI. */ + + athn_start_noisefloor_calib(sc, 1); + timeout_add_msec(&sc->calib_to, 500); + break; + } + + return (sc->sc_newstate(ic, nstate, arg)); +#endif + return 0; +} + +void +athn_updateedca(struct ieee80211com *ic) +{ +#define ATHN_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */ + struct athn_softc *sc = ic->ic_softc; + const struct ieee80211_edca_ac_params *ac; + int aci, qid; +#if OpenBSD_IEEE80211_API + for (aci = 0; aci < WME_NUM_AC; aci++) { + ac = &ic->ic_edca_ac[aci]; + qid = athn_ac2qid[aci]; + + AR_WRITE(sc, AR_DLCL_IFS(qid), + SM(AR_D_LCL_IFS_CWMIN, ATHN_EXP2(ac->ac_ecwmin)) | + SM(AR_D_LCL_IFS_CWMAX, ATHN_EXP2(ac->ac_ecwmax)) | + SM(AR_D_LCL_IFS_AIFS, ac->ac_aifsn)); + if (ac->ac_txoplimit != 0) { + AR_WRITE(sc, AR_DCHNTIME(qid), + SM(AR_D_CHNTIME_DUR, + IEEE80211_TXOP_TO_US(ac->ac_txoplimit)) | + AR_D_CHNTIME_EN); + } else + AR_WRITE(sc, AR_DCHNTIME(qid), 0); + } + AR_WRITE_BARRIER(sc); +#undef ATHN_EXP2 +#endif +} + +int +athn_clock_rate(struct athn_softc *sc) +{ + __attribute__((unused)) struct ieee80211com *ic = &sc->sc_ic; + int clockrate; /* MHz. */ +#if OpenBSD_IEEE80211_API + /* + * AR9287 v1.3+ MAC runs at 117MHz (instead of 88/44MHz) when + * ASYNC FIFO is enabled. + */ + if (AR_SREV_9287_13_OR_LATER(sc) && !AR_SREV_9380_10_OR_LATER(sc)) + clockrate = 117; + // TODO no member named 'ic_bss' in 'struct ieee80211com' + else if (ic->ic_bss->ni_chan != IEEE80211_CHAN_ANYC && + IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan)) { + if (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK) + clockrate = AR_CLOCK_RATE_FAST_5GHZ_OFDM; + else + clockrate = AR_CLOCK_RATE_5GHZ_OFDM; + } else if (ic->ic_curmode == IEEE80211_MODE_11B) { + clockrate = AR_CLOCK_RATE_CCK; + } else + clockrate = AR_CLOCK_RATE_2GHZ_OFDM; + if (sc->curchanext != NULL) + clockrate *= 2; + + return (clockrate); +#endif + return 0; +} + +int +athn_chan_sifs(struct ieee80211_channel *c) +{ + return IEEE80211_IS_CHAN_2GHZ(c) ? IEEE80211_DUR_DS_SIFS : 16; +} + +void +athn_setsifs(struct athn_softc *sc) +{ + int sifs = 0; //athn_chan_sifs(sc->sc_ic.ic_bss->ni_chan); // TODO no member named 'ic_bss' in 'struct ieee80211com' + AR_WRITE(sc, AR_D_GBL_IFS_SIFS, (sifs - 2) * athn_clock_rate(sc)); + AR_WRITE_BARRIER(sc); +} + +int +athn_acktimeout(struct ieee80211_channel *c, int slot) +{ + int sifs = athn_chan_sifs(c); + int ackto = sifs + slot; + + /* Workaround for early ACK timeouts. */ + if (IEEE80211_IS_CHAN_2GHZ(c)) + ackto += 64 - sifs - slot; + + return ackto; +} + +void +athn_setacktimeout(struct athn_softc *sc, struct ieee80211_channel *c, int slot) +{ + int ackto = athn_acktimeout(c, slot); + uint32_t reg = AR_READ(sc, AR_TIME_OUT); + reg = RW(reg, AR_TIME_OUT_ACK, ackto * athn_clock_rate(sc)); + AR_WRITE(sc, AR_TIME_OUT, reg); + AR_WRITE_BARRIER(sc); +} + +void +athn_setctstimeout(struct athn_softc *sc, struct ieee80211_channel *c, int slot) +{ + int ctsto = athn_acktimeout(c, slot); + int sifs = athn_chan_sifs(c); + uint32_t reg = AR_READ(sc, AR_TIME_OUT); + + /* Workaround for early CTS timeouts. */ + if (IEEE80211_IS_CHAN_2GHZ(c)) + ctsto += 48 - sifs - slot; + + reg = RW(reg, AR_TIME_OUT_CTS, ctsto * athn_clock_rate(sc)); + AR_WRITE(sc, AR_TIME_OUT, reg); + AR_WRITE_BARRIER(sc); +} + +void +athn_setclockrate(struct athn_softc *sc) +{ + int clockrate = athn_clock_rate(sc); + uint32_t reg = AR_READ(sc, AR_USEC); + reg = RW(reg, AR_USEC_USEC, clockrate - 1); + AR_WRITE(sc, AR_USEC, reg); + AR_WRITE_BARRIER(sc); +} + +void +athn_updateslot(struct ieee80211com *ic) +{ + struct athn_softc *sc = ic->ic_softc; + int slot; + +#if OpenBSD_IEEE80211_API + slot = (ic->ic_flags & IEEE80211_F_SHSLOT) ? + IEEE80211_DUR_DS_SHSLOT : IEEE80211_DUR_DS_SLOT; + AR_WRITE(sc, AR_D_GBL_IFS_SLOT, slot * athn_clock_rate(sc)); + AR_WRITE_BARRIER(sc); + + // TODO no member named 'ic_bss' in 'struct ieee80211com' + // athn_setacktimeout(sc, ic->ic_bss->ni_chan, slot); + // athn_setctstimeout(sc, ic->ic_bss->ni_chan, slot); +#endif +} + +void +athn_start(struct ifnet *ifp) +{ + struct athn_softc *sc = ifp->if_softc; + __attribute__((unused)) struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_node *ni; + struct mbuf *m; + + if (!(ifp->if_flags & IFF_DRV_RUNNING) || ifq_is_oactive()) + return; + +#if OpenBSD_IEEE80211_API + for (;;) { + if (SIMPLEQ_EMPTY(&sc->txbufs)) { + ifq_set_oactive(); + break; + } + /* Send pending management frames first. */ + //OpenBSD->FreeBSD prev code: + //m = mq_dequeue(&ic->ic_mgtq); +// m = ml_dequeue(&ic->ic_mgtq.mq_list); + if (m != NULL) { + ni = m->m_pkthdr.ph_cookie; + goto sendit; + } + if (ic->ic_state != IEEE80211_S_RUN) + break; + + //OpenBSD->FreeBSD prev code: + //m = mq_dequeue(&ic->ic_pwrsaveq); +// m = ml_dequeue(&ic->ic_pwrsaveq.mq_list); + if (m != NULL) { + ni = m->m_pkthdr.ph_cookie; + goto sendit; + } + if (ic->ic_state != IEEE80211_S_RUN) + break; + + /* Encapsulate and send data frames. */ + ALTQ_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; +#if NBPFILTER > 0 + if (ifp->if_bpf != NULL) + bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); +#endif + if ((m = ieee80211_encap(ifp, m, &ni)) == NULL) + continue; + sendit: +#if NBPFILTER > 0 + if (ic->ic_rawbpf != NULL) + bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT); +#endif + if (sc->ops.tx(sc, m, ni, 0) != 0) { + ieee80211_release_node(ic, ni); + continue; + } + + sc->sc_tx_timer = 5; + } +#endif +} + +void +athn_watchdog(struct ifnet *ifp) +{ + struct athn_softc *sc = ifp->if_softc; + + + if (sc->sc_tx_timer > 0) { + if (--sc->sc_tx_timer == 0) { + // TOTO missing field 'dv_xname' in 'struct device' + // printf("%s: device timeout\n", sc->sc_dev.dv_xname); + athn_stop(ifp, 1); + (void)athn_init(ifp); + return; + } + } +#if OpenBSD_IEEE80211_API + ieee80211_watchdog(ifp); +#endif +} + +void +athn_set_multi(struct athn_softc *sc) +{ +#if OpenBSD_IEEE80211_API + struct arpcom *ac = &sc->sc_ic.ic_ac; + struct ifnet *ifp = &ac->ac_if; + struct ether_multi *enm; + struct ether_multistep step; + const uint8_t *addr; + uint32_t val, lo, hi; + uint8_t bit; + + if (ac->ac_multirangecnt > 0) + ifp->if_flags |= IFF_ALLMULTI; + + if ((ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) != 0) { + lo = hi = 0xffffffff; + goto done; + } + lo = hi = 0; + ETHER_FIRST_MULTI(step, ac, enm); + while (enm != NULL) { + addr = enm->enm_addrlo; + /* Calculate the XOR value of all eight 6-bit words. */ + val = addr[0] | addr[1] << 8 | addr[2] << 16; + bit = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; + val = addr[3] | addr[4] << 8 | addr[5] << 16; + bit ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; + bit &= 0x3f; + if (bit < 32) + lo |= 1 << bit; + else + hi |= 1 << (bit - 32); + ETHER_NEXT_MULTI(step, enm); + } + done: + AR_WRITE(sc, AR_MCAST_FIL0, lo); + AR_WRITE(sc, AR_MCAST_FIL1, hi); + AR_WRITE_BARRIER(sc); +#endif +} + +int +athn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +{ + struct athn_softc *sc = ifp->if_softc; + __attribute__((unused)) struct ieee80211com *ic = &sc->sc_ic; + struct ifreq *ifr; + int s, error = 0; + + s = splnet(); + + switch (cmd) { + case SIOCSIFADDR: + ifp->if_flags |= IFF_UP; + /* FALLTHROUGH */ + case SIOCSIFFLAGS: + if (ifp->if_flags & IFF_UP) { + if ((ifp->if_flags & IFF_DRV_RUNNING) && + ((ifp->if_flags ^ sc->sc_if_flags) & + (IFF_ALLMULTI | IFF_PROMISC)) != 0) { + athn_set_multi(sc); + } else if (!(ifp->if_flags & IFF_DRV_RUNNING)) + error = athn_init(ifp); + } else { + if (ifp->if_flags & IFF_DRV_RUNNING) + athn_stop(ifp, 1); + } + sc->sc_if_flags = ifp->if_flags; + break; + + case SIOCADDMULTI: + case SIOCDELMULTI: + ifr = (struct ifreq *)data; +#if OpenBSD_IEEE80211_API + error = (cmd == SIOCADDMULTI) ? + ether_addmulti(ifr, &ic->ic_ac) : + ether_delmulti(ifr, &ic->ic_ac); + + if (error == ENETRESET) { + athn_set_multi(sc); + error = 0; + } +#endif + break; +#if OpenBSD_IEEE80211_API + case SIOCS80211CHANNEL: + error = ieee80211_ioctl(ifp, cmd, data); + if (error == ENETRESET && + ic->ic_opmode == IEEE80211_M_MONITOR) { + if ((ifp->if_flags & (IFF_UP | IFF_DRV_RUNNING)) == + (IFF_UP | IFF_DRV_RUNNING)) + athn_switch_chan(sc, ic->ic_ibss_chan, NULL); + error = 0; + } + break; +#endif + default: + error = ieee80211_ioctl(ifp, cmd, data); + } + + if (error == ENETRESET) { + error = 0; + if ((ifp->if_flags & (IFF_UP | IFF_DRV_RUNNING)) == + (IFF_UP | IFF_DRV_RUNNING)) { + athn_stop(ifp, 0); + error = athn_init(ifp); + } + } + + splx(s); + return (error); +} + +int +athn_init(struct ifnet *ifp) +{ + struct athn_softc *sc = ifp->if_softc; + struct athn_ops *ops = &sc->ops; + __attribute__((unused)) struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_channel *c = NULL, *extc; + int i, error; + + // TODO no member named 'ic_bss' in 'struct ieee80211com' + // c = ic->ic_bss->ni_chan = ic->ic_ibss_chan; + extc = NULL; + + /* In case a new MAC address has been configured. */ +#if OpenBSD_IEEE80211_API + IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); +#endif + /* For CardBus, power on the socket. */ + if (sc->sc_enable != NULL) { + if ((error = sc->sc_enable(sc)) != 0) { + // TOTO missing field 'dv_xname' in 'struct device' + // printf("%s: could not enable device\n", + // sc->sc_dev.dv_xname); + goto fail; + } + ATHN_LOCK(sc); + if ((error = athn_reset_power_on(sc)) != 0) { + // TOTO missing field 'dv_xname' in 'struct device' + // printf("%s: could not power on device\n", + // sc->sc_dev.dv_xname); + ATHN_UNLOCK(sc); + goto fail; + } + ATHN_UNLOCK(sc); + } + + athn_config_nonpcie(sc); + + + ops->enable_antenna_diversity(sc); + +#ifdef ATHN_BT_COEXISTENCE + /* Configure bluetooth coexistence for combo chips. */ + if (sc->flags & ATHN_FLAG_BTCOEX) + athn_btcoex_init(sc); +#endif + + /* Configure LED. */ + ATHN_LOCK(sc); + athn_led_init(sc); + ATHN_UNLOCK(sc); + + /* Configure hardware radio switch. */ + if (sc->flags & ATHN_FLAG_RFSILENT) + ops->rfsilent_init(sc); + + if ((error = athn_hw_reset(sc, c, extc, 1)) != 0) { + // TOTO missing field 'dv_xname' in 'struct device' + // printf("%s: unable to reset hardware; reset status %d\n", + // sc->sc_dev.dv_xname, error); + goto fail; + } + + athn_config_ht(sc); + + /* Enable Rx. */ + athn_rx_start(sc); + + /* Reset HW key cache entries. */ + for (i = 0; i < sc->kc_entries; i++) + athn_reset_key(sc, i); + + /* Enable interrupts. */ + athn_enable_interrupts(sc); + +#ifdef ATHN_BT_COEXISTENCE + /* Enable bluetooth coexistence for combo chips. */ + if (sc->flags & ATHN_FLAG_BTCOEX) + athn_btcoex_enable(sc); +#endif + + ifq_clr_oactive(); + ifp->if_flags |= IFF_DRV_RUNNING; + +#ifdef notyet + if (ic->ic_flags & IEEE80211_F_WEPON) { + /* Configure WEP keys. */ + for (i = 0; i < IEEE80211_WEP_NKID; i++) + athn_set_key(ic, NULL, &ic->ic_nw_keys[i]); + } +#endif +#if OpenBSD_IEEE80211_API + if (ic->ic_opmode == IEEE80211_M_MONITOR) + ieee80211_new_state(ic, IEEE80211_S_RUN, -1); + else + ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); +#endif + return (0); + fail: + athn_stop(ifp, 1); + return (error); +} + +void +athn_stop(struct ifnet *ifp, int disable) +{ + struct athn_softc *sc = ifp->if_softc; + __attribute__((unused)) struct ieee80211com *ic = &sc->sc_ic; + int qid, i; + + ifp->if_flags &= ~IFF_DRV_RUNNING; + ifq_clr_oactive(); + +// timeout_del(&sc->scan_to); + +// ieee80211_new_state(ic, IEEE80211_S_INIT, -1); + +#ifdef ATHN_BT_COEXISTENCE + /* Disable bluetooth coexistence for combo chips. */ + if (sc->flags & ATHN_FLAG_BTCOEX) + athn_btcoex_disable(sc); +#endif + + /* Disable interrupts. */ + athn_disable_interrupts(sc); + /* Acknowledge interrupts (avoids interrupt storms). */ + AR_WRITE(sc, AR_INTR_SYNC_CAUSE, 0xffffffff); + AR_WRITE(sc, AR_INTR_SYNC_MASK, 0); + + for (qid = 0; qid < ATHN_QID_COUNT; qid++) + athn_stop_tx_dma(sc, qid); + /* XXX call athn_hw_reset if Tx still pending? */ + for (qid = 0; qid < ATHN_QID_COUNT; qid++) + athn_tx_reclaim(sc, qid); + + /* Stop Rx. */ + AR_SETBITS(sc, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT); + AR_WRITE(sc, AR_MIBC, AR_MIBC_FMC); + AR_WRITE(sc, AR_MIBC, AR_MIBC_CMC); + AR_WRITE(sc, AR_FILT_OFDM, 0); + AR_WRITE(sc, AR_FILT_CCK, 0); + AR_WRITE_BARRIER(sc); + athn_set_rxfilter(sc, 0); + athn_stop_rx_dma(sc); + + /* Reset HW key cache entries. */ + for (i = 0; i < sc->kc_entries; i++) + athn_reset_key(sc, i); + + ATHN_LOCK(sc); + athn_reset(sc, 0); + athn_init_pll(sc, NULL); + athn_set_power_awake(sc); + athn_reset(sc, 1); + athn_init_pll(sc, NULL); + ATHN_UNLOCK(sc); + + athn_set_power_sleep(sc); + + /* For CardBus, power down the socket. */ + if (disable && sc->sc_disable != NULL) + sc->sc_disable(sc); +} + +void +athn_suspend(struct athn_softc *sc) +{ +#if OpenBSD_IEEE80211_API + struct ifnet *ifp = &sc->sc_ic.ic_if; + + if (ifp->if_flags & IFF_DRV_RUNNING) + athn_stop(ifp, 1); +#endif +} + +void +athn_wakeup(struct athn_softc *sc) +{ +#if OpenBSD_IEEE80211_API + struct ifnet *ifp = &sc->sc_ic.ic_if; + + if (ifp->if_flags & IFF_UP) + athn_init(ifp); +#endif +} diff --git a/sys/dev/athn/athn_stubs.c b/sys/dev/athn/athn_stubs.c new file mode 100644 --- /dev/null +++ b/sys/dev/athn/athn_stubs.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include /* uintptr_t */ +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "athnreg.h" +#include "athnvar.h" + +// Not needed anymore after adding ar9285reg.h +// int ar9285_attach(struct athn_softc *sc) +// { +// printf("%s is stub", __FUNCTION__); +// return 0; +// } + +// int ar9285_init_calib(struct athn_softc *sc, +// struct ieee80211_channel *c, struct ieee80211_channel *extc) +// { +// printf("%s is stub", __FUNCTION__); +// return 0; +// } + +// void ar9271_pa_calib(struct athn_softc *sc) +// { +// printf("%s is stub", __FUNCTION__); +// } diff --git a/sys/dev/athn/headers/ar5008reg.h b/sys/dev/athn/headers/ar5008reg.h new file mode 100644 --- /dev/null +++ b/sys/dev/athn/headers/ar5008reg.h @@ -0,0 +1,1038 @@ +/* $OpenBSD: ar5008reg.h,v 1.7 2020/04/27 08:21:34 stsp Exp $ */ + +/*- + * Copyright (c) 2009 Damien Bergamini + * Copyright (c) 2008-2009 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +// TODO: use ifndef +#pragma once +/* + * MAC registers. + */ +#define AR_ISR_S2_S 0x00cc +#define AR_ISR_S3_S 0x00d0 +#define AR_ISR_S4_S 0x00d4 +#define AR_ISR_S5_S 0x00d8 +#define AR_GPIO_IN_OUT 0x4048 +#define AR_GPIO_OE_OUT 0x404c +#define AR_GPIO_INTR_POL 0x4050 +#define AR_GPIO_INPUT_EN_VAL 0x4054 +#define AR_GPIO_INPUT_MUX1 0x4058 +#define AR_GPIO_INPUT_MUX2 0x405c +#define AR_GPIO_OUTPUT_MUX(i) (0x4060 + (i) * 4) +#define AR_INPUT_STATE 0x406c +#define AR_EEPROM_STATUS_DATA 0x407c +#define AR_OBS 0x4080 +#define AR_GPIO_PDPU 0x4088 +#define AR_PCIE_MSI 0x4094 + +/* + * Analog registers. + */ +#define AR_IS_ANALOG_REG(reg) ((reg) >= 0x7800 && (reg) <= 0x78b4) +#define AR_AN_RF2G1_CH0 0x7810 +#define AR_AN_RF5G1_CH0 0x7818 +#define AR_AN_RF2G1_CH1 0x7834 +#define AR_AN_RF5G1_CH1 0x783c +#define AR_AN_SYNTH9 0x7868 +#define AR_AN_TOP1 0x7890 +#define AR_AN_TOP2 0x7894 + +/* + * PHY registers. + */ +#define AR_PHY_BASE 0x9800 +#define AR_PHY(i) (AR_PHY_BASE + (i) * 4) +#define AR_PHY_TEST 0x9800 +#define AR_PHY_TURBO 0x9804 +#define AR_PHY_TEST2 0x9808 +#define AR_PHY_TIMING2 0x9810 +#define AR_PHY_TIMING3 0x9814 +#define AR_PHY_CHIP_ID 0x9818 +#define AR_PHY_ACTIVE 0x981c +#define AR_PHY_RF_CTL2 0x9824 +#define AR_PHY_RF_CTL3 0x9828 +#define AR_PHY_ADC_CTL 0x982c +#define AR_PHY_ADC_SERIAL_CTL 0x9830 +#define AR_PHY_RF_CTL4 0x9834 +#define AR_PHY_TSTDAC_CONST 0x983c +#define AR_PHY_SETTLING 0x9844 +#define AR_PHY_RXGAIN 0x9848 +#define AR_PHY_DESIRED_SZ 0x9850 +#define AR_PHY_FIND_SIG 0x9858 +#define AR_PHY_AGC_CTL1 0x985c +#define AR_PHY_AGC_CONTROL 0x9860 +#define AR_PHY_CCA(i) (0x9864 + (i) * 0x1000) +#define AR_PHY_SFCORR 0x9868 +#define AR_PHY_SFCORR_LOW 0x986c +#define AR_PHY_SLEEP_CTR_CONTROL 0x9870 +#define AR_PHY_SLEEP_CTR_LIMIT 0x9874 +#define AR_PHY_SLEEP_SCAL 0x9878 +#define AR_PHY_PLL_CTL 0x987c +#define AR_PHY_BIN_MASK_1 0x9900 +#define AR_PHY_BIN_MASK_2 0x9904 +#define AR_PHY_BIN_MASK_3 0x9908 +#define AR_PHY_MASK_CTL 0x990c +#define AR_PHY_RX_DELAY 0x9914 +#define AR_PHY_SEARCH_START_DELAY 0x9918 +#define AR_PHY_TIMING_CTRL4_0 0x9920 +#define AR_PHY_TIMING_CTRL4(i) (0x9920 + (i) * 0x1000) +#define AR_PHY_TIMING5 0x9924 +#define AR_PHY_POWER_TX_RATE1 0x9934 +#define AR_PHY_POWER_TX_RATE2 0x9938 +#define AR_PHY_POWER_TX_RATE_MAX 0x993c +#define AR_PHY_RADAR_EXT 0x9940 +#define AR_PHY_FRAME_CTL 0x9944 +#define AR_PHY_SPUR_REG 0x994c +#define AR_PHY_RADAR_0 0x9954 +#define AR_PHY_RADAR_1 0x9958 +#define AR_PHY_SWITCH_CHAIN_0 0x9960 +#define AR_PHY_SWITCH_COM 0x9964 +#define AR_PHY_SIGMA_DELTA 0x996c +#define AR_PHY_RESTART 0x9970 +#define AR_PHY_RFBUS_REQ 0x997c +#define AR_PHY_TIMING7 0x9980 +#define AR_PHY_TIMING8 0x9984 +#define AR_PHY_BIN_MASK2_1 0x9988 +#define AR_PHY_BIN_MASK2_2 0x998c +#define AR_PHY_BIN_MASK2_3 0x9990 +#define AR_PHY_BIN_MASK2_4 0x9994 +#define AR_PHY_TIMING9 0x9998 +#define AR_PHY_TIMING10 0x999c +#define AR_PHY_TIMING11 0x99a0 +#define AR_PHY_RX_CHAINMASK 0x99a4 +#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac +#define AR_PHY_NEW_ADC_DC_GAIN_CORR(i) (0x99b4 + (i) * 0x1000) +#define AR_PHY_EXT_CCA0 0x99b8 +#define AR_PHY_EXT_CCA(i) (0x99bc + (i) * 0x1000) +#define AR_PHY_SFCORR_EXT 0x99c0 +#define AR_PHY_HALFGI 0x99d0 +#define AR_PHY_CHANNEL_MASK_01_30 0x99d4 +#define AR_PHY_CHANNEL_MASK_31_60 0x99d8 +#define AR_PHY_CHAN_INFO_MEMORY 0x99dc +#define AR_PHY_HEAVY_CLIP_ENABLE 0x99e0 +#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS 0x99ec +#define AR_PHY_CALMODE 0x99f0 +#define AR_PHY_REFCLKDLY 0x99f4 +#define AR_PHY_REFCLKPD 0x99f8 +#define AR_PHY_BB_RFGAIN(i) (0x9a00 + (i) * 4) +#define AR_PHY_CAL_MEAS_0(i) (0x9c10 + (i) * 0x1000) +#define AR_PHY_CAL_MEAS_1(i) (0x9c14 + (i) * 0x1000) +#define AR_PHY_CAL_MEAS_2(i) (0x9c18 + (i) * 0x1000) +#define AR_PHY_CAL_MEAS_3(i) (0x9c1c + (i) * 0x1000) +#define AR_PHY_CURRENT_RSSI 0x9c1c +#define AR_PHY_RFBUS_GRANT 0x9c20 +#define AR9280_PHY_CURRENT_RSSI 0x9c3c +#define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9cf4 +#define AR_PHY_CHAN_INFO_GAIN 0x9cfc +#define AR_PHY_MODE 0xa200 +#define AR_PHY_CCK_TX_CTRL 0xa204 +#define AR_PHY_CCK_DETECT 0xa208 +#define AR_PHY_GAIN_2GHZ 0xa20c +#define AR_PHY_CCK_RXCTRL4 0xa21c +#define AR_PHY_DAG_CTRLCCK 0xa228 +#define AR_PHY_FORCE_CLKEN_CCK 0xa22c +#define AR_PHY_POWER_TX_RATE3 0xa234 +#define AR_PHY_POWER_TX_RATE4 0xa238 +#define AR_PHY_SCRM_SEQ_XR 0xa23c +#define AR_PHY_HEADER_DETECT_XR 0xa240 +#define AR_PHY_CHIRP_DETECTED_XR 0xa244 +#define AR_PHY_BLUETOOTH 0xa254 +#define AR_PHY_TPCRG1 0xa258 +#define AR_PHY_TX_PWRCTRL4 0xa264 +#define AR_PHY_ANALOG_SWAP 0xa268 +#define AR_PHY_TPCRG5 0xa26c +#define AR_PHY_TX_PWRCTRL6_0 0xa270 +#define AR_PHY_TX_PWRCTRL7 0xa274 +#define AR_PHY_TX_PWRCTRL9 0xa27c +#define AR_PHY_PDADC_TBL_BASE 0xa280 +#define AR_PHY_TX_GAIN_TBL(i) (0xa300 + (i) * 4) +#define AR_PHY_CL_CAL_CTL 0xa358 +#define AR_PHY_CLC_TBL(i) (0xa35c + (i) * 4) +#define AR_PHY_POWER_TX_RATE5 0xa38c +#define AR_PHY_POWER_TX_RATE6 0xa390 +#define AR_PHY_CH0_TX_PWRCTRL11 0xa398 +#define AR_PHY_CAL_CHAINMASK 0xa39c +#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0 +#define AR_PHY_VIT_MASK2_M_31_45 0xa3a4 +#define AR_PHY_VIT_MASK2_M_16_30 0xa3a8 +#define AR_PHY_VIT_MASK2_M_00_15 0xa3ac +#define AR_PHY_PILOT_MASK_01_30 0xa3b0 +#define AR_PHY_PILOT_MASK_31_60 0xa3b4 +#define AR_PHY_VIT_MASK2_P_15_01 0xa3b8 +#define AR_PHY_VIT_MASK2_P_30_16 0xa3bc +#define AR_PHY_VIT_MASK2_P_45_31 0xa3c0 +#define AR_PHY_VIT_MASK2_P_61_46 0xa3c4 +#define AR_PHY_POWER_TX_SUB 0xa3c8 +#define AR_PHY_POWER_TX_RATE7 0xa3cc +#define AR_PHY_POWER_TX_RATE8 0xa3d0 +#define AR_PHY_POWER_TX_RATE9 0xa3d4 +#define AR_PHY_XPA_CFG 0xa3d8 +#define AR_PHY_TX_PWRCTRL6_1 0xb270 +#define AR_PHY_CH1_TX_PWRCTRL11 0xb398 + +/* + * AR7010 registers. + */ +#define AR7010_GPIO_OE 0x52000 +#define AR7010_GPIO_IN 0x52004 +#define AR7010_GPIO_OUT 0x52008 + + +/* Bits for AR_AN_RF2G1_CH0. */ +#define AR_AN_RF2G1_CH0_OB_M 0x03800000 +#define AR_AN_RF2G1_CH0_OB_S 23 +#define AR_AN_RF2G1_CH0_DB_M 0x1c000000 +#define AR_AN_RF2G1_CH0_DB_S 26 + +/* Bits for AR_AN_RF5G1_CH0. */ +#define AR_AN_RF5G1_CH0_OB5_M 0x00070000 +#define AR_AN_RF5G1_CH0_OB5_S 16 +#define AR_AN_RF5G1_CH0_DB5_M 0x00380000 +#define AR_AN_RF5G1_CH0_DB5_S 19 + +/* Bits for AR_AN_RF2G1_CH1. */ +#define AR_AN_RF2G1_CH1_OB_M 0x03800000 +#define AR_AN_RF2G1_CH1_OB_S 23 +#define AR_AN_RF2G1_CH1_DB_M 0x1c000000 +#define AR_AN_RF2G1_CH1_DB_S 26 + +/* Bits for AR_AN_RF5G1_CH1. */ +#define AR_AN_RF5G1_CH1_OB5_M 0x00070000 +#define AR_AN_RF5G1_CH1_OB5_S 16 +#define AR_AN_RF5G1_CH1_DB5_M 0x00380000 +#define AR_AN_RF5G1_CH1_DB5_S 19 + +/* Bits for AR_AN_SYNTH9. */ +#define AR_AN_SYNTH9_REFDIVA_M 0xf8000000 +#define AR_AN_SYNTH9_REFDIVA_S 27 + +/* Bits for AR_AN_TOP1. */ +#define AR_AN_TOP1_DACLPMODE 0x00040000 + +/* Bits for AR_AN_TOP2. */ +#define AR_AN_TOP2_XPABIAS_LVL_M 0xc0000000 +#define AR_AN_TOP2_XPABIAS_LVL_S 30 +#define AR_AN_TOP2_LOCALBIAS 0x00200000 +#define AR_AN_TOP2_PWDCLKIND 0x00400000 + +/* Bits for AR_PHY_TEST. */ +#define AR_PHY_TEST_RFSILENT_BB 0x00002000 +#define AR_PHY_TEST_AGC_CLR 0x10000000 + +/* Bits for AR_PHY_TURBO. */ +#define AR_PHY_FC_TURBO_MODE 0x00000001 +#define AR_PHY_FC_TURBO_SHORT 0x00000002 +#define AR_PHY_FC_DYN2040_EN 0x00000004 +#define AR_PHY_FC_DYN2040_PRI_ONLY 0x00000008 +#define AR_PHY_FC_DYN2040_PRI_CH 0x00000010 +#define AR_PHY_FC_DYN2040_EXT_CH 0x00000020 +#define AR_PHY_FC_HT_EN 0x00000040 +#define AR_PHY_FC_SHORT_GI_40 0x00000080 +#define AR_PHY_FC_WALSH 0x00000100 +#define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200 +#define AR_PHY_FC_ENABLE_DAC_FIFO 0x00000800 + +/* Bits for AR_PHY_TIMING3. */ +#define AR_PHY_TIMING3_DSC_MAN_M 0xfffe0000 +#define AR_PHY_TIMING3_DSC_MAN_S 17 +#define AR_PHY_TIMING3_DSC_EXP_M 0x0001e000 +#define AR_PHY_TIMING3_DSC_EXP_S 13 + +/* Bits for AR_PHY_CHIP_ID. */ +#define AR_PHY_CHIP_ID_REV_0 0x00000080 +#define AR_PHY_CHIP_ID_REV_1 0x00000081 +#define AR_PHY_CHIP_ID_9160_REV_0 0x000000b0 + +/* Bits for AR_PHY_ACTIVE. */ +#define AR_PHY_ACTIVE_EN 0x00000001 +#define AR_PHY_ACTIVE_DIS 0x00000000 + +/* Bits for AR_PHY_RF_CTL2. */ +#define AR_PHY_TX_END_DATA_START_M 0x000000ff +#define AR_PHY_TX_END_DATA_START_S 0 +#define AR_PHY_TX_END_PA_ON_M 0x0000ff00 +#define AR_PHY_TX_END_PA_ON_S 8 + +/* Bits for AR_PHY_RF_CTL3. */ +#define AR_PHY_TX_END_TO_A2_RX_ON_M 0x00ff0000 +#define AR_PHY_TX_END_TO_A2_RX_ON_S 16 + +/* Bits for AR_PHY_ADC_CTL. */ +#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_M 0x00000003 +#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S 0 +#define AR_PHY_ADC_CTL_OFF_PWDDAC 0x00002000 +#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000 +#define AR_PHY_ADC_CTL_OFF_PWDADC 0x00008000 +#define AR_PHY_ADC_CTL_ON_INBUFGAIN_M 0x00030000 +#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S 16 + +/* Bits for AR_PHY_ADC_SERIAL_CTL. */ +#define AR_PHY_SEL_INTERNAL_ADDAC 0x00000000 +#define AR_PHY_SEL_EXTERNAL_RADIO 0x00000001 + +/* Bits for AR_PHY_RF_CTL4. */ +#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_M 0xff000000 +#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24 +#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_M 0x00ff0000 +#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16 +#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_M 0x0000ff00 +#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S 8 +#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_M 0x000000ff +#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0 + +/* Bits for AR_PHY_SETTLING. */ +#define AR_PHY_SETTLING_SWITCH_M 0x00003f80 +#define AR_PHY_SETTLING_SWITCH_S 7 + +/* Bits for AR_PHY_RXGAIN. */ +#define AR_PHY_RXGAIN_TXRX_ATTEN_M 0x0003f000 +#define AR_PHY_RXGAIN_TXRX_ATTEN_S 12 +#define AR_PHY_RXGAIN_TXRX_RF_MAX_M 0x007c0000 +#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18 +#define AR9280_PHY_RXGAIN_TXRX_ATTEN_M 0x00003f80 +#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7 +#define AR9280_PHY_RXGAIN_TXRX_MARGIN_M 0x001fc000 +#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14 + +/* Bits for AR_PHY_DESIRED_SZ. */ +#define AR_PHY_DESIRED_SZ_ADC_M 0x000000ff +#define AR_PHY_DESIRED_SZ_ADC_S 0 +#define AR_PHY_DESIRED_SZ_PGA_M 0x0000ff00 +#define AR_PHY_DESIRED_SZ_PGA_S 8 +#define AR_PHY_DESIRED_SZ_TOT_DES_M 0x0ff00000 +#define AR_PHY_DESIRED_SZ_TOT_DES_S 20 + +/* Bits for AR_PHY_FIND_SIG. */ +#define AR_PHY_FIND_SIG_FIRSTEP_M 0x0003f000 +#define AR_PHY_FIND_SIG_FIRSTEP_S 12 +#define AR_PHY_FIND_SIG_FIRPWR_M 0x03fc0000 +#define AR_PHY_FIND_SIG_FIRPWR_S 18 + +/* Bits for AR_PHY_AGC_CTL1. */ +#define AR_PHY_AGC_CTL1_COARSE_LOW_M 0x00007f80 +#define AR_PHY_AGC_CTL1_COARSE_LOW_S 7 +#define AR_PHY_AGC_CTL1_COARSE_HIGH_M 0x003f8000 +#define AR_PHY_AGC_CTL1_COARSE_HIGH_S 15 + +/* Bits for AR_PHY_AGC_CONTROL. */ +#define AR_PHY_AGC_CONTROL_CAL 0x00000001 +#define AR_PHY_AGC_CONTROL_NF 0x00000002 +#define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000 +#define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000 +#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 + +/* Bits for AR_PHY_CCA. */ +#define AR_PHY_MAXCCA_PWR_M 0x000001ff +#define AR_PHY_MAXCCA_PWR_S 0 +#define AR_PHY_CCA_THRESH62_M 0x0007f000 +#define AR_PHY_CCA_THRESH62_S 12 +#define AR_PHY_MINCCA_PWR_M 0x0ff80000 +#define AR_PHY_MINCCA_PWR_S 19 +#define AR9280_PHY_CCA_THRESH62_M 0x000ff000 +#define AR9280_PHY_CCA_THRESH62_S 12 +#define AR9280_PHY_MINCCA_PWR_M 0x1ff00000 +#define AR9280_PHY_MINCCA_PWR_S 20 + +/* Bits for AR_PHY_SFCORR_LOW. */ +#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001 +#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_M 0x00003f00 +#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8 +#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_M 0x001fc000 +#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14 +#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_M 0x0fe00000 +#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21 + +/* Bits for AR_PHY_SFCORR. */ +#define AR_PHY_SFCORR_M2COUNT_THR_M 0x0000001f +#define AR_PHY_SFCORR_M2COUNT_THR_S 0 +#define AR_PHY_SFCORR_M1_THRESH_M 0x00fe0000 +#define AR_PHY_SFCORR_M1_THRESH_S 17 +#define AR_PHY_SFCORR_M2_THRESH_M 0x7f000000 +#define AR_PHY_SFCORR_M2_THRESH_S 24 + +/* Bits for AR_PHY_RX_DELAY. */ +#define AR_PHY_RX_DELAY_DELAY_M 0x00003fff +#define AR_PHY_RX_DELAY_DELAY_S 0 + +/* Bits for AR_PHY_TIMING_CTRL4_0. */ +#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_M 0x0000001f +#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0 +#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_M 0x000007e0 +#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5 +#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x00000800 +#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_M 0x0000f000 +#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12 +#define AR_PHY_TIMING_CTRL4_DO_CAL 0x00010000 +#define AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000 +#define AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000 +#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000 +#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000 + +/* Bits for AR_PHY_TIMING5. */ +#define AR_PHY_TIMING5_CYCPWR_THR1_M 0x000000fe +#define AR_PHY_TIMING5_CYCPWR_THR1_S 1 + +/* Bits for AR_PHY_POWER_TX_RATE_MAX. */ +#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040 + +/* Bits for AR_PHY_FRAME_CTL. */ +#define AR_PHY_FRAME_CTL_TX_CLIP_M 0x00000038 +#define AR_PHY_FRAME_CTL_TX_CLIP_S 3 + +/* Bits for AR_PHY_TXPWRADJ. */ +#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_M 0x00000fc0 +#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S 6 +#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_M 0x00fc0000 +#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18 + +/* Bits for AR_PHY_RADAR_EXT. */ +#define AR_PHY_RADAR_EXT_ENA 0x00004000 + +/* Bits for AR_PHY_RADAR_0. */ +#define AR_PHY_RADAR_0_ENA 0x00000001 +#define AR_PHY_RADAR_0_INBAND_M 0x0000003e +#define AR_PHY_RADAR_0_INBAND_S 1 +#define AR_PHY_RADAR_0_PRSSI_M 0x00000fc0 +#define AR_PHY_RADAR_0_PRSSI_S 6 +#define AR_PHY_RADAR_0_HEIGHT_M 0x0003f000 +#define AR_PHY_RADAR_0_HEIGHT_S 12 +#define AR_PHY_RADAR_0_RRSSI_M 0x00fc0000 +#define AR_PHY_RADAR_0_RRSSI_S 18 +#define AR_PHY_RADAR_0_FIRPWR_M 0x7f000000 +#define AR_PHY_RADAR_0_FIRPWR_S 24 +#define AR_PHY_RADAR_0_FFT_ENA 0x80000000 + +/* Bits for AR_PHY_RADAR_1. */ +#define AR_PHY_RADAR_1_MAXLEN_M 0x000000ff +#define AR_PHY_RADAR_1_MAXLEN_S 0 +#define AR_PHY_RADAR_1_RELSTEP_THRESH_M 0x00001f00 +#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8 +#define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000 +#define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000 +#define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000 +#define AR_PHY_RADAR_1_RELPWR_THRESH_M 0x003f0000 +#define AR_PHY_RADAR_1_RELPWR_THRESH_S 16 +#define AR_PHY_RADAR_1_USE_FIR128 0x00400000 +#define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000 + +/* Bits for AR_PHY_SIGMA_DELTA. */ +#define AR_PHY_SIGMA_DELTA_ADC_SEL_M 0x00000003 +#define AR_PHY_SIGMA_DELTA_ADC_SEL_S 0 +#define AR_PHY_SIGMA_DELTA_FILT2_M 0x000000f8 +#define AR_PHY_SIGMA_DELTA_FILT2_S 3 +#define AR_PHY_SIGMA_DELTA_FILT1_M 0x00001f00 +#define AR_PHY_SIGMA_DELTA_FILT1_S 8 +#define AR_PHY_SIGMA_DELTA_ADC_CLIP_M 0x01ffe000 +#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13 + +/* Bits for AR_PHY_RESTART. */ +#define AR_PHY_RESTART_DIV_GC_M 0x001c0000 +#define AR_PHY_RESTART_DIV_GC_S 18 + +/* Bits for AR_PHY_RFBUS_REQ. */ +#define AR_PHY_RFBUS_REQ_EN 0x00000001 + +/* Bits for AR_PHY_TIMING11. */ +#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_M 0x000fffff +#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0 +#define AR_PHY_TIMING11_SPUR_FREQ_SD_M 0x3ff00000 +#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 +#define AR_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000 +#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000 + +/* Bits for AR_PHY_NEW_ADC_DC_GAIN_CORR(). */ +#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000 +#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000 + +/* Bits for AR_PHY_EXT_CCA0. */ +#define AR_PHY_EXT_CCA0_THRESH62_M 0x000000ff +#define AR_PHY_EXT_CCA0_THRESH62_S 0 + +/* Bits for AR_PHY_EXT_CCA. */ +#define AR_PHY_EXT_MAXCCA_PWR_M 0x000001ff +#define AR_PHY_EXT_MAXCCA_PWR_S 0 +#define AR_PHY_EXT_CCA_CYCPWR_THR1_M 0x0000fe00 +#define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9 +#define AR_PHY_EXT_CCA_THRESH62_M 0x007f0000 +#define AR_PHY_EXT_CCA_THRESH62_S 16 +#define AR_PHY_EXT_MINCCA_PWR_M 0xff800000 +#define AR_PHY_EXT_MINCCA_PWR_S 23 +#define AR9280_PHY_EXT_MINCCA_PWR_M 0x01ff0000 +#define AR9280_PHY_EXT_MINCCA_PWR_S 16 + +/* Bits for AR_PHY_SFCORR_EXT. */ +#define AR_PHY_SFCORR_EXT_M1_THRESH_M 0x0000007f +#define AR_PHY_SFCORR_EXT_M1_THRESH_S 0 +#define AR_PHY_SFCORR_EXT_M2_THRESH_M 0x00003f80 +#define AR_PHY_SFCORR_EXT_M2_THRESH_S 7 +#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_M 0x001fc000 +#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14 +#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_M 0x0fe00000 +#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21 +#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_M 0xf0000000 +#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28 + +/* Bits for AR_PHY_HALFGI. */ +#define AR_PHY_HALFGI_DSC_EXP_M 0x0000000f +#define AR_PHY_HALFGI_DSC_EXP_S 0 +#define AR_PHY_HALFGI_DSC_MAN_M 0x0007fff0 +#define AR_PHY_HALFGI_DSC_MAN_S 4 + +/* Bits for AR_PHY_CHAN_INFO_MEMORY. */ +#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x00000001 + +/* Bits for AR_PHY_HEAVY_CLIP_FACTOR_RIFS. */ +#define AR_PHY_RIFS_INIT_DELAY_M 0x03ff0000 +#define AR_PHY_RIFS_INIT_DELAY_S 16 + +/* Bits for AR_PHY_CALMODE. */ +#define AR_PHY_CALMODE_IQ 0x00000000 +#define AR_PHY_CALMODE_ADC_GAIN 0x00000001 +#define AR_PHY_CALMODE_ADC_DC_PER 0x00000002 +#define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003 + +/* Bits for AR_PHY_RFBUS_GRANT. */ +#define AR_PHY_RFBUS_GRANT_EN 0x00000001 + +/* Bits for AR_PHY_CHAN_INFO_GAIN_DIFF. */ +#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320 + +/* Bits for AR_PHY_MODE. */ +#define AR_PHY_MODE_ASYNCFIFO 0x00000080 +#define AR_PHY_MODE_AR2133 0x00000008 +#define AR_PHY_MODE_AR5111 0x00000000 +#define AR_PHY_MODE_AR5112 0x00000008 +#define AR_PHY_MODE_DYNAMIC 0x00000004 +#define AR_PHY_MODE_RF2GHZ 0x00000002 +#define AR_PHY_MODE_RF5GHZ 0x00000000 +#define AR_PHY_MODE_CCK 0x00000001 +#define AR_PHY_MODE_OFDM 0x00000000 +#define AR_PHY_MODE_DYN_CCK_DISABLE 0x00000100 + +/* Bits for AR_PHY_CCK_TX_CTRL. */ +#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_M 0x0000000c +#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2 +#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010 + +/* Bits for AR_PHY_CCK_DETECT. */ +#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_M 0x0000003f +#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0 +#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_M 0x00001fc0 +#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6 +#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x00002000 + +/* Bits for AR_PHY_GAIN_2GHZ. */ +#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_M 0x0000003f +#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S 0 +#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_M 0x0000001f +#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S 0 +#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_M 0x00000fc0 +#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S 6 +#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_M 0x00003c00 +#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S 10 +#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_M 0x0001f000 +#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12 +#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_M 0x003e0000 +#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17 +#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_M 0x00fc0000 +#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18 + +/* Bit for AR_PHY_CCK_RXCTRL4. */ +#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_M 0x01f80000 +#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19 + +/* Bits for AR_PHY_DAG_CTRLCCK. */ +#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200 +#define AR_PHY_DAG_CTRLCCK_RSSI_THR_M 0x0001fc00 +#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10 + +/* Bits for AR_PHY_FORCE_CLKEN_CCK. */ +#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX 0x00000040 + +/* Bits for AR_PHY_TPCRG1. */ +#define AR_PHY_TPCRG1_NUM_PD_GAIN_M 0x0000c000 +#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14 +#define AR_PHY_TPCRG1_PD_GAIN_1_M 0x00030000 +#define AR_PHY_TPCRG1_PD_GAIN_1_S 16 +#define AR_PHY_TPCRG1_PD_GAIN_2_M 0x000c0000 +#define AR_PHY_TPCRG1_PD_GAIN_2_S 18 +#define AR_PHY_TPCRG1_PD_GAIN_3_M 0x00300000 +#define AR_PHY_TPCRG1_PD_GAIN_3_S 20 +#define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000 + +/* Bits for AR_PHY_TX_PWRCTRL4. */ +#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001 +#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_M 0x000001fe +#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1 + +/* Bits for AR_PHY_TX_PWRCTRL6_[01]. */ +#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_M 0x03000000 +#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24 + +/* Bits for AR_PHY_TX_PWRCTRL7. */ +#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX_M 0x0007e000 +#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX_S 13 +#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_M 0x01f80000 +#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 + +/* Bits for AR_PHY_TX_PWRCTRL9. */ +#define AR_PHY_TX_DESIRED_SCALE_CCK_M 0x00007c00 +#define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 /* XXX should be 9? */ +#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 + +/* Bits for AR_PHY_TX_GAIN_TBL. */ +#define AR_PHY_TX_GAIN_CLC_M 0x0000001e +#define AR_PHY_TX_GAIN_CLC_S 1 +#define AR_PHY_TX_GAIN_M 0x0007f000 +#define AR_PHY_TX_GAIN_S 12 + +/* Bits for AR_PHY_SPUR_REG. */ +#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_M 0x0000007f +#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0 +#define AR_SPUR_RSSI_THRESH 40 +#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x00000100 +#define AR_PHY_SPUR_REG_MASK_RATE_SELECT 0x0001fe00 +#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x00020000 +#define AR_PHY_SPUR_REG_MASK_RATE_CNTL 0x03fc0000 + +/* Bits for AR_PHY_ANALOG_SWAP. */ +#define AR_PHY_SWAP_ALT_CHAIN 0x00000040 + +/* Bits for AR_PHY_TPCRG5. */ +#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_M 0x0000000f +#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_M 0x000003f0 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_M 0x0000fc00 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_M 0x003f0000 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_M 0x0fc00000 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22 + +/* Bits for AR_PHY_CL_CAL_CTL. */ +#define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001 +#define AR_PHY_CL_CAL_ENABLE 0x00000002 + +/* Bits for AR_PHY_CLC_TBL. */ +#define AR_PHY_CLC_Q0_M 0x0000ffd0 +#define AR_PHY_CLC_Q0_S 5 +#define AR_PHY_CLC_I0_M 0x07ff0000 +#define AR_PHY_CLC_I0_S 16 + +/* Bits for AR_PHY_XPA_CFG. */ +#define AR_PHY_FORCE_XPA_CFG 0x000000001 + +/* Bits for AR_PHY_CH[01]_TX_PWRCTRL11. */ +#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_M 0x0000fc00 +#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10 +#define AR_PHY_TX_PWRCTRL_OLPC_PWR_M 0x00ff0000 +#define AR_PHY_TX_PWRCTRL_OLPC_PWR_S 16 + +/* Bits for AR_PHY_NEW_ADC_DC_GAIN_CORR. */ +#define AR_PHY_NEW_ADC_DC_GAIN_QGAIN_M 0x0000003f +#define AR_PHY_NEW_ADC_DC_GAIN_QGAIN_S 0 +#define AR_PHY_NEW_ADC_DC_GAIN_IGAIN_M 0x00000fc0 +#define AR_PHY_NEW_ADC_DC_GAIN_IGAIN_S 6 +#define AR_PHY_NEW_ADC_DC_GAIN_QDC_M 0x001ff000 +#define AR_PHY_NEW_ADC_DC_GAIN_QDC_S 12 +#define AR_PHY_NEW_ADC_DC_GAIN_IDC_M 0x3fe00000 +#define AR_PHY_NEW_ADC_DC_GAIN_IDC_S 21 + +/* Bits for AR_PHY(0x37). */ +#define AR5416_BMODE_SYNTH 0x00000002 +#define AR5416_AMODE_REFSEL_M 0x0000000c +#define AR5416_AMODE_REFSEL_S 2 + + +#define AR5008_MAX_SCATTER 16 /* NB: not a hardware limit. */ + +/* + * Tx DMA descriptor. + */ +struct ar_tx_desc { + uint32_t ds_link; + uint32_t ds_data; + uint32_t ds_ctl0; + uint32_t ds_ctl1; + uint32_t ds_ctl2; + uint32_t ds_ctl3; + uint32_t ds_ctl4; + uint32_t ds_ctl5; + uint32_t ds_ctl6; + uint32_t ds_ctl7; + uint32_t ds_ctl8; + uint32_t ds_ctl9; + uint32_t ds_ctl10; + uint32_t ds_ctl11; + uint32_t ds_status0; + uint32_t ds_status1; + uint32_t ds_tstamp; + uint32_t ds_ba_bitmap_lo; + uint32_t ds_ba_bitmap_hi; + uint32_t ds_evm0; + uint32_t ds_evm1; + uint32_t ds_evm2; + uint32_t ds_status8; + uint32_t ds_status9; + /* + * Padding to make Tx descriptors 128 bytes such that they will + * not cross a 4KB boundary. + */ + uint32_t pad[8]; +} __packed __attribute__((aligned(4))); + +/* Bits for ds_ctl0. */ +#define AR_TXC0_FRAME_LEN_M 0x00000fff +#define AR_TXC0_FRAME_LEN_S 0 +#define AR_TXC0_VIRT_MORE_FRAG 0x00001000 +#define AR_TXC0_XMIT_POWER_M 0x003f0000 +#define AR_TXC0_XMIT_POWER_S 16 +#define AR_TXC0_RTS_ENABLE 0x00400000 +#define AR_TXC0_VEOL 0x00800000 +#define AR_TXC0_CLR_DEST_MASK 0x01000000 +#define AR_TXC0_INTR_REQ 0x20000000 +#define AR_TXC0_DEST_IDX_VALID 0x40000000 +#define AR_TXC0_CTS_ENABLE 0x80000000 + +/* Bits for ds_ctl1. */ +#define AR_TXC1_BUF_LEN_M 0x00000fff +#define AR_TXC1_BUF_LEN_S 0 +#define AR_TXC1_MORE 0x00001000 +#define AR_TXC1_DEST_IDX_M 0x000fe000 +#define AR_TXC1_DEST_IDX_S 13 +#define AR_TXC1_FRAME_TYPE_M 0x00f00000 +#define AR_TXC1_FRAME_TYPE_S 20 +#define AR_FRAME_TYPE_NORMAL 0 +#define AR_FRAME_TYPE_ATIM 1 +#define AR_FRAME_TYPE_PSPOLL 2 +#define AR_FRAME_TYPE_BEACON 3 +#define AR_FRAME_TYPE_PROBE_RESP 4 +#define AR_TXC1_NO_ACK 0x01000000 +#define AR_TXC1_INSERT_TS 0x02000000 +#define AR_TXC1_EXT_ONLY 0x08000000 +#define AR_TXC1_EXT_AND_CTL 0x10000000 +#define AR_TXC1_MORE_AGGR 0x20000000 +#define AR_TXC1_IS_AGGR 0x40000000 + +/* Bits for ds_ctl2. */ +#define AR_TXC2_BURST_DUR_M 0x00007fff +#define AR_TXC2_BURST_DUR_S 0 +#define AR_TXC2_DUR_UPDATE_ENA 0x00008000 +#define AR_TXC2_XMIT_DATA_TRIES0_M 0x000f0000 +#define AR_TXC2_XMIT_DATA_TRIES0_S 16 +#define AR_TXC2_XMIT_DATA_TRIES1_M 0x00f00000 +#define AR_TXC2_XMIT_DATA_TRIES1_S 20 +#define AR_TXC2_XMIT_DATA_TRIES2_M 0x0f000000 +#define AR_TXC2_XMIT_DATA_TRIES2_S 24 +#define AR_TXC2_XMIT_DATA_TRIES3_M 0xf0000000 +#define AR_TXC2_XMIT_DATA_TRIES3_S 28 + +/* Bits for ds_ctl3. */ +#define AR_TXC3_XMIT_RATE0_M 0x000000ff +#define AR_TXC3_XMIT_RATE0_S 0 +#define AR_TXC3_XMIT_RATE1_M 0x0000ff00 +#define AR_TXC3_XMIT_RATE1_S 8 +#define AR_TXC3_XMIT_RATE2_M 0x00ff0000 +#define AR_TXC3_XMIT_RATE2_S 16 +#define AR_TXC3_XMIT_RATE3_M 0xff000000 +#define AR_TXC3_XMIT_RATE3_S 24 + +/* Bits for ds_ctl4. */ +#define AR_TXC4_PACKET_DUR0_M 0x00007fff +#define AR_TXC4_PACKET_DUR0_S 0 +#define AR_TXC4_RTSCTS_QUAL0 0x00008000 +#define AR_TXC4_PACKET_DUR1_M 0x7fff0000 +#define AR_TXC4_PACKET_DUR1_S 16 +#define AR_TXC4_RTSCTS_QUAL1 0x80000000 +/* Shortcut. */ +#define AR_TXC4_RTSCTS_QUAL01 \ + (AR_TXC4_RTSCTS_QUAL0 | AR_TXC4_RTSCTS_QUAL1) + +/* Bits for ds_ctl5. */ +#define AR_TXC5_PACKET_DUR2_M 0x00007fff +#define AR_TXC5_PACKET_DUR2_S 0 +#define AR_TXC5_RTSCTS_QUAL2 0x00008000 +#define AR_TXC5_PACKET_DUR3_M 0x7fff0000 +#define AR_TXC5_PACKET_DUR3_S 16 +#define AR_TXC5_RTSCTS_QUAL3 0x80000000 +/* Shortcut. */ +#define AR_TXC5_RTSCTS_QUAL23 \ + (AR_TXC5_RTSCTS_QUAL2 | AR_TXC5_RTSCTS_QUAL3) + +/* Bits for ds_ctl6. */ +#define AR_TXC6_AGGR_LEN_M 0x0000ffff +#define AR_TXC6_AGGR_LEN_S 0 +#define AR_TXC6_PAD_DELIM_M 0x03fc0000 +#define AR_TXC6_PAD_DELIM_S 18 +#define AR_TXC6_ENCR_TYPE_M 0x0c000000 +#define AR_TXC6_ENCR_TYPE_S 26 +#define AR_ENCR_TYPE_CLEAR 0 +#define AR_ENCR_TYPE_WEP 1 +#define AR_ENCR_TYPE_AES 2 +#define AR_ENCR_TYPE_TKIP 3 + +/* Bits for ds_ctl7. */ +#define AR_TXC7_2040_0 0x00000001 +#define AR_TXC7_GI0 0x00000002 +#define AR_TXC7_CHAIN_SEL0_M 0x0000001c +#define AR_TXC7_CHAIN_SEL0_S 2 +#define AR_TXC7_2040_1 0x00000020 +#define AR_TXC7_GI1 0x00000040 +#define AR_TXC7_CHAIN_SEL1_M 0x00000380 +#define AR_TXC7_CHAIN_SEL1_S 7 +#define AR_TXC7_2040_2 0x00000400 +#define AR_TXC7_GI2 0x00000800 +#define AR_TXC7_CHAIN_SEL2_M 0x00007000 +#define AR_TXC7_CHAIN_SEL2_S 12 +#define AR_TXC7_2040_3 0x00008000 +#define AR_TXC7_GI3 0x00010000 +#define AR_TXC7_CHAIN_SEL3_M 0x000e0000 +#define AR_TXC7_CHAIN_SEL3_S 17 +#define AR_TXC7_RTSCTS_RATE_M 0x0ff00000 +#define AR_TXC7_RTSCTS_RATE_S 20 +/* Shortcuts. */ +#define AR_TXC7_2040_0123 \ + (AR_TXC7_2040_0 | AR_TXC7_2040_1 | AR_TXC7_2040_2 | AR_TXC7_2040_3) +#define AR_TXC7_GI0123 \ + (AR_TXC7_GI0 | AR_TXC7_GI1 | AR_TXC7_GI2 | AR_TXC7_GI3) + +/* Bits for ds_ctl9. */ +#define AR_TXC9_XMIT_POWER1_M 0x3f000000 +#define AR_TXC9_XMIT_POWER1_S 24 + +/* Bits for ds_ctl10. */ +#define AR_TXC10_XMIT_POWER2_M 0x3f000000 +#define AR_TXC10_XMIT_POWER2_S 24 + +/* Bits for ds_ctl11. */ +#define AR_TXC11_XMIT_POWER3_M 0x3f000000 +#define AR_TXC11_XMIT_POWER3_S 24 + +/* Bits for ds_status0. */ +#define AR_TXS0_RSSI_ANT0(i) (((x) >> ((i) * 8)) & 0xff) +#define AR_TXS0_BA_STATUS 0x40000000 + +/* Bits for ds_status1. */ +#define AR_TXS1_FRM_XMIT_OK 0x00000001 +#define AR_TXS1_EXCESSIVE_RETRIES 0x00000002 +#define AR_TXS1_FIFO_UNDERRUN 0x00000004 +#define AR_TXS1_FILTERED 0x00000008 +#define AR_TXS1_RTS_FAIL_CNT_M 0x000000f0 +#define AR_TXS1_RTS_FAIL_CNT_S 4 +#define AR_TXS1_DATA_FAIL_CNT_M 0x00000f00 +#define AR_TXS1_DATA_FAIL_CNT_S 8 +#define AR_TXS1_VIRT_RETRY_CNT_M 0x0000f000 +#define AR_TXS1_VIRT_RETRY_CNT_S 12 +#define AR_TXS1_TX_DELIM_UNDERRUN 0x00010000 +#define AR_TXS1_TX_DATA_UNDERRUN 0x00020000 +#define AR_TXS1_DESC_CFG_ERR 0x00040000 +#define AR_TXS1_TX_TIMER_EXPIRED 0x00080000 +/* Shortcut. */ +#define AR_TXS1_UNDERRUN \ + (AR_TXS1_FIFO_UNDERRUN | \ + AR_TXS1_TX_DELIM_UNDERRUN | \ + AR_TXS1_TX_DATA_UNDERRUN) + +/* Bits for ds_status9. */ +#define AR_TXS9_DONE 0x00000001 +#define AR_TXS9_SEQNUM_M 0x00001ffe +#define AR_TXS9_SEQNUM_S 1 +#define AR_TXS9_TXOP_EXCEEDED 0x00020000 +#define AR_TXS9_FINAL_IDX_M 0x00600000 +#define AR_TXS9_FINAL_IDX_S 21 +#define AR_TXS9_POWER_MGMT 0x02000000 + +/* + * Rx DMA descriptor. + */ +struct ar_rx_desc { + uint32_t ds_link; + uint32_t ds_data; + uint32_t ds_ctl0; + uint32_t ds_ctl1; + uint32_t ds_status0; + uint32_t ds_status1; + uint32_t ds_status2; + uint32_t ds_status3; + uint32_t ds_status4; + uint32_t ds_status5; + uint32_t ds_status6; + uint32_t ds_status7; + uint32_t ds_status8; + /* + * Padding to make Rx descriptors 64 bytes such that they will + * not cross a 4KB boundary. + */ + uint32_t pad[3]; +} __packed __attribute__((aligned(4))); + +/* Bits for ds_ctl1. */ +#define AR_RXC1_BUF_LEN_M 0x00000fff +#define AR_RXC1_BUF_LEN_S 0 +#define AR_RXC1_INTR_REQ 0x00002000 + +/* Bits for ds_status0. */ +#define AR_RXS0_RSSI_ANT00(x) (((x) >> 0) & 0xff) +#define AR_RXS0_RSSI_ANT01(x) (((x) >> 8) & 0xff) +#define AR_RXS0_RSSI_ANT02(x) (((x) >> 16) & 0xff) +#define AR_RXS0_RATE_M 0xff000000 +#define AR_RXS0_RATE_S 24 + +/* Bits for ds_status1. */ +#define AR_RXS1_DATA_LEN_M 0x00000fff +#define AR_RXS1_DATA_LEN_S 0 +#define AR_RXS1_MORE 0x00001000 + +/* Bits for ds_status3. */ +#define AR_RXS3_GI 0x00000001 +#define AR_RXS3_2040 0x00000002 +#define AR_RXS3_PARALLEL_40 0x00000004 +#define AR_RXS3_ANTENNA_M 0xffffff00 +#define AR_RXS3_ANTENNA_S 8 +#define AR_RXS3_RATE_M 0x000003fc +#define AR_RXS3_RATE_S 2 + +/* Bits for ds_status4. */ +#define AR_RXS0_RSSI_ANT10(x) (((x) >> 0) & 0xff) +#define AR_RXS0_RSSI_ANT11(x) (((x) >> 8) & 0xff) +#define AR_RXS0_RSSI_ANT12(x) (((x) >> 16) & 0xff) +#define AR_RXS4_RSSI_COMBINED_M 0xff000000 +#define AR_RXS4_RSSI_COMBINED_S 24 + +/* Bits for ds_status8. */ +#define AR_RXS8_DONE 0x00000001 +#define AR_RXS8_FRAME_OK 0x00000002 +#define AR_RXS8_CRC_ERR 0x00000004 +#define AR_RXS8_DECRYPT_CRC_ERR 0x00000008 +#define AR_RXS8_PHY_ERR 0x00000010 +#define AR_RXS8_MICHAEL_ERR 0x00000020 +#define AR_RXS8_PRE_DELIM_CRC_ERR 0x00000040 +#define AR_RXS8_PHY_ERR_CODE_M 0x0000ff00 +#define AR_RXS8_PHY_ERR_CODE_S 8 +#define AR_RXS8_KEY_IDX_VALID 0x00000100 +#define AR_RXS8_KEY_IDX_M 0x0000fe00 +#define AR_RXS8_KEY_IDX_S 9 +#define AR_RXS8_POST_DELIM_CRC_ERR 0x00040000 +#define AR_RXS8_DECRYPT_BUSY_ERR 0x40000000 +#define AR_RXS8_KEY_MISS 0x80000000 + +#define AR_MAX_PWR_RANGE_IN_HALF_DB 64 +#define AR9285_PD_GAIN_BOUNDARY_DEFAULT 58 + +/* + * AR5008 family common ROM header. + */ +#define AR_EEPROM_MAGIC_OFFSET 0x0000 +#if BYTE_ORDER == BIG_ENDIAN +#define AR_EEPROM_MAGIC 0x5aa5 +#else +#define AR_EEPROM_MAGIC 0xa55a +#endif + +#define AR_NO_SPUR 0x8000 +#define AR_NUM_PDADC_VALUES 128 + +struct ar_base_eep_header { + uint16_t length; + uint16_t checksum; + uint16_t version; +#define AR_EEP_VER 0xe +#define AR_EEP_VER_MINOR_MASK 0x0fff +#define AR_EEP_MINOR_VER_2 2 +#define AR_EEP_MINOR_VER_3 3 +#define AR_EEP_MINOR_VER_7 7 +#define AR_EEP_MINOR_VER_9 9 +#define AR_EEP_MINOR_VER_10 10 +#define AR_EEP_MINOR_VER_16 16 +#define AR_EEP_MINOR_VER_17 17 +#define AR_EEP_MINOR_VER_19 19 +#define AR_EEP_MINOR_VER_20 20 +#define AR_EEP_MINOR_VER_21 21 +#define AR_EEP_MINOR_VER_22 22 + + uint8_t opCapFlags; +#define AR_OPFLAGS_11A 0x01 +#define AR_OPFLAGS_11G 0x02 +/* NB: If set, 11n is _disabled_ in the corresponding mode: */ +#define AR_OPFLAGS_11N_5G40 0x04 +#define AR_OPFLAGS_11N_2G40 0x08 +#define AR_OPFLAGS_11N_5G20 0x10 +#define AR_OPFLAGS_11N_2G20 0x20 + + uint8_t eepMisc; + uint16_t regDmn[2]; + uint8_t macAddr[6]; + uint8_t rxMask; + uint8_t txMask; + uint16_t rfSilent; +#define AR_EEP_RFSILENT_ENABLED 0x0001 +#define AR_EEP_RFSILENT_GPIO_SEL_M 0x001c +#define AR_EEP_RFSILENT_GPIO_SEL_S 2 +#define AR_EEP_RFSILENT_POLARITY 0x0002 + + uint16_t blueToothOptions; + uint16_t deviceCap; +#define AR_EEP_DEVCAP_COMPRESS_DIS 0x0001 +#define AR_EEP_DEVCAP_AES_DIS 0x0002 +#define AR_EEP_DEVCAP_FASTFRAME_DIS 0x0004 +#define AR_EEP_DEVCAP_BURST_DIS 0x0008 +#define AR_EEP_DEVCAP_MAXQCU_M 0x01f0 +#define AR_EEP_DEVCAP_MAXQCU_S 4 +#define AR_EEP_DEVCAP_HEAVY_CLIP_EN 0x0200 +#define AR_EEP_DEVCAP_KC_ENTRIES_M 0xf000 +#define AR_EEP_DEVCAP_KC_ENTRIES_S 12 + + uint32_t binBuildNumber; + uint8_t deviceType; +} __packed; + +#define AR_EEP_TXGAIN_ORIGINAL 0 +#define AR_EEP_TXGAIN_HIGH_POWER 1 + +#define AR_EEPROM_MODAL_SPURS 5 + +struct ar_spur_chan { + uint16_t spurChan; + uint8_t spurRangeLow; + uint8_t spurRangeHigh; +} __packed; + +struct ar_cal_data_per_freq_olpc { + uint8_t pwrPdg[2][5]; + uint8_t vpdPdg[2][5]; + uint8_t pcdac[2][5]; + uint8_t empty[2][5]; +} __packed; + +struct ar_cal_target_power_leg { + uint8_t bChannel; + uint8_t tPow2x[4]; +} __packed; + +struct ar_cal_target_power_ht { + uint8_t bChannel; + uint8_t tPow2x[8]; +} __packed; + +struct ar_cal_ctl_edges { + uint8_t bChannel; + uint8_t tPowerFlag; +#define AR_CAL_CTL_EDGES_POWER_M 0x3f +#define AR_CAL_CTL_EDGES_POWER_S 0 +#define AR_CAL_CTL_EDGES_FLAG_M 0xc0 +#define AR_CAL_CTL_EDGES_FLAG_S 6 +} __packed; diff --git a/sys/dev/athn/headers/ar5416reg.h b/sys/dev/athn/headers/ar5416reg.h new file mode 100644 --- /dev/null +++ b/sys/dev/athn/headers/ar5416reg.h @@ -0,0 +1,841 @@ +/* $OpenBSD: ar5416reg.h,v 1.7 2019/02/01 16:15:07 stsp Exp $ */ + +/*- + * Copyright (c) 2009 Damien Bergamini + * Copyright (c) 2008-2009 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define AR5416_MAX_CHAINS 3 + +#define AR5416_PHY_CCA_MIN_GOOD_VAL_2GHZ (-100) +#define AR5416_PHY_CCA_MIN_GOOD_VAL_5GHZ (-110) +#define AR5416_PHY_CCA_MAX_GOOD_VAL_2GHZ (-80) +#define AR5416_PHY_CCA_MAX_GOOD_VAL_5GHZ (-90) + +/* + * ROM layout used by AR5416, AR9160 and AR9280. + */ +#define AR5416_EEP_START_LOC 256 +#define AR5416_NUM_5G_CAL_PIERS 8 +#define AR5416_NUM_2G_CAL_PIERS 4 +#define AR5416_NUM_5G_20_TARGET_POWERS 8 +#define AR5416_NUM_5G_40_TARGET_POWERS 8 +#define AR5416_NUM_2G_CCK_TARGET_POWERS 3 +#define AR5416_NUM_2G_20_TARGET_POWERS 4 +#define AR5416_NUM_2G_40_TARGET_POWERS 4 +#define AR5416_NUM_CTLS 24 +#define AR5416_NUM_BAND_EDGES 8 +#define AR5416_NUM_PD_GAINS 4 +#define AR5416_PD_GAINS_IN_MASK 4 +#define AR5416_PD_GAIN_ICEPTS 5 + +struct ar5416_base_eep_header { + uint16_t length; + uint16_t checksum; + uint16_t version; + uint8_t opCapFlags; + uint8_t eepMisc; + uint16_t regDmn[2]; + uint8_t macAddr[6]; + uint8_t rxMask; + uint8_t txMask; + uint16_t rfSilent; + uint16_t blueToothOptions; + uint16_t deviceCap; + uint32_t binBuildNumber; + uint8_t deviceType; + /* End of common header. */ + uint8_t pwdclkind; + uint8_t fastClk5g; + uint8_t divChain; + uint8_t rxGainType; +#define AR5416_EEP_RXGAIN_23DB_BACKOFF 0 +#define AR5416_EEP_RXGAIN_13DB_BACKOFF 1 +#define AR5416_EEP_RXGAIN_ORIG 2 + + uint8_t dacHiPwrMode_5G; + uint8_t openLoopPwrCntl; + uint8_t dacLpMode; + uint8_t txGainType; + uint8_t rcChainMask; + uint8_t desiredScaleCCK; + uint8_t pwrTableOffset; + uint8_t frac_n_5g; + uint8_t futureBase[21]; +} __packed; + +struct ar5416_modal_eep_header { + uint32_t antCtrlChain[AR5416_MAX_CHAINS]; + uint32_t antCtrlCommon; + uint8_t antennaGainCh[AR5416_MAX_CHAINS]; + uint8_t switchSettling; + uint8_t txRxAttenCh[AR5416_MAX_CHAINS]; + uint8_t rxTxMarginCh[AR5416_MAX_CHAINS]; + uint8_t adcDesiredSize; + uint8_t pgaDesiredSize; + uint8_t xlnaGainCh[AR5416_MAX_CHAINS]; + uint8_t txEndToXpaOff; + uint8_t txEndToRxOn; + uint8_t txFrameToXpaOn; + uint8_t thresh62; + uint8_t noiseFloorThreshCh[AR5416_MAX_CHAINS]; + uint8_t xpdGain; + uint8_t xpd; + uint8_t iqCalICh[AR5416_MAX_CHAINS]; + uint8_t iqCalQCh[AR5416_MAX_CHAINS]; + uint8_t pdGainOverlap; + uint8_t ob; + uint8_t db; + uint8_t xpaBiasLvl; + uint8_t pwrDecreaseFor2Chain; + uint8_t pwrDecreaseFor3Chain; + uint8_t txFrameToDataStart; + uint8_t txFrameToPaOn; + uint8_t ht40PowerIncForPdadc; + uint8_t bswAtten[AR5416_MAX_CHAINS]; + uint8_t bswMargin[AR5416_MAX_CHAINS]; + uint8_t swSettleHt40; + uint8_t xatten2Db[AR5416_MAX_CHAINS]; + uint8_t xatten2Margin[AR5416_MAX_CHAINS]; + uint8_t ob_ch1; + uint8_t db_ch1; + uint8_t flagBits; +#define AR5416_EEP_FLAG_USEANT1 0x01 +#define AR5416_EEP_FLAG_FORCEXPAON 0x02 +#define AR5416_EEP_FLAG_LOCALBIAS 0x04 +#define AR5416_EEP_FLAG_FEMBANDSELECT 0x08 +#define AR5416_EEP_FLAG_XLNABUFIN 0x10 +#define AR5416_EEP_FLAG_XLNAISEL_M 0x60 +#define AR5416_EEP_FLAG_XLNAISEL_S 5 +#define AR5416_EEP_FLAG_XLNABUFMODE 0x80 + + uint8_t miscBits; +#define AR5416_EEP_MISC_TX_DAC_SCALE_CCK_M 0x03 +#define AR5416_EEP_MISC_TX_DAC_SCALE_CCK_S 0 +#define AR5416_EEP_MISC_TX_CLIP_M 0xfc +#define AR5416_EEP_MISC_TX_CLIP_S 2 + + uint16_t xpaBiasLvlFreq[3]; + uint8_t futureModal[6]; + struct ar_spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; +} __packed; + +struct ar5416_cal_data_per_freq { + uint8_t pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; + uint8_t vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; +} __packed; + +struct ar5416_cal_ctl_data { + struct ar_cal_ctl_edges + ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; +} __packed; + +struct ar5416_eeprom { + struct ar5416_base_eep_header baseEepHeader; + uint8_t custData[64]; + struct ar5416_modal_eep_header modalHeader[2]; + uint8_t calFreqPier5G[AR5416_NUM_5G_CAL_PIERS]; + uint8_t calFreqPier2G[AR5416_NUM_2G_CAL_PIERS]; + struct ar5416_cal_data_per_freq + calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS]; + struct ar5416_cal_data_per_freq + calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS]; + struct ar_cal_target_power_leg + calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS]; + struct ar_cal_target_power_ht + calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS]; + struct ar_cal_target_power_ht + calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS]; + struct ar_cal_target_power_leg + calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS]; + struct ar_cal_target_power_leg + calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS]; + struct ar_cal_target_power_ht + calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS]; + struct ar_cal_target_power_ht + calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS]; + uint8_t ctlIndex[AR5416_NUM_CTLS]; + struct ar5416_cal_ctl_data ctlData[AR5416_NUM_CTLS]; + uint8_t padding; +} __packed; + +/* Macro to "pack" registers to 16-bit to save some .rodata space. */ +#define P(x) (x) + +/* + * AR5416 initialization values. + */ +static const uint16_t ar5416_regs[] = { + P(0x01030), P(0x01070), P(0x010b0), P(0x010f0), P(0x08014), + P(0x0801c), P(0x08120), P(0x081d0), P(0x09804), P(0x09820), + P(0x09824), P(0x09828), P(0x09834), P(0x09838), P(0x09844), + P(0x09848), P(0x0a848), P(0x0b848), P(0x09850), P(0x09858), + P(0x0985c), P(0x09860), P(0x09864), P(0x09868), P(0x0986c), + P(0x09914), P(0x09918), P(0x09924), P(0x09944), P(0x09960), + P(0x0a960), P(0x0b960), P(0x09964), P(0x099bc), P(0x099c0), + P(0x099c4), P(0x099c8), P(0x099cc), P(0x099d0), P(0x099d4), + P(0x099d8), P(0x0a204), P(0x0a208), P(0x0a20c), P(0x0b20c), + P(0x0c20c), P(0x0a21c), P(0x0a230), P(0x0a274), P(0x0a300), + P(0x0a304), P(0x0a308), P(0x0a30c), P(0x0a310), P(0x0a314), + P(0x0a318), P(0x0a31c), P(0x0a320), P(0x0a324), P(0x0a328), + P(0x0a32c), P(0x0a330), P(0x0a334) +}; + +static const uint32_t ar5416_vals_5g20[] = { + 0x00000230, 0x00000168, 0x00000e60, 0x0000a000, 0x03e803e8, + 0x128d93a7, 0x08f04800, 0x00003210, 0x00000300, 0x02020200, + 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x1372161e, + 0x001a6a65, 0x001a6a65, 0x001a6a65, 0x6c48b4e0, 0x7ec82d2e, + 0x31395d5e, 0x00049d18, 0x0001ce00, 0x409a4190, 0x050cb081, + 0x000007d0, 0x000001b8, 0xd0058a0b, 0xffb81020, 0x00000900, + 0x00000900, 0x00000900, 0x00000000, 0x001a0a00, 0x038919be, + 0x06336f77, 0x6af6532c, 0x08f186c8, 0x00046384, 0x00000000, + 0x00000000, 0x00000880, 0xd6be4788, 0x002ec1e0, 0x002ec1e0, + 0x002ec1e0, 0x1883800a, 0x00000000, 0x0a1a9caa, 0x18010000, + 0x30032602, 0x48073e06, 0x560b4c0a, 0x641a600f, 0x7a4f6e1b, + 0x8c5b7e5a, 0x9d0f96cf, 0xb51fa69f, 0xcb3fbd07, 0x0000d7bf, + 0x00000000, 0x00000000, 0x00000000 +}; + +static const uint32_t ar5416_vals_5g40[] = { + 0x00000460, 0x000002d0, 0x00001cc0, 0x00014000, 0x07d007d0, + 0x128d93cf, 0x08f04800, 0x00003210, 0x000003c4, 0x02020200, + 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x1372161e, + 0x001a6a65, 0x001a6a65, 0x001a6a65, 0x6d48b4e0, 0x7ec82d2e, + 0x3139605e, 0x00049d18, 0x0001ce00, 0x409a4190, 0x050cb081, + 0x00000fa0, 0x00000370, 0xd0058a0b, 0xffb81020, 0x00000900, + 0x00000900, 0x00000900, 0x00000000, 0x001a0a00, 0x038919be, + 0x06336f77, 0x6af6532c, 0x08f186c8, 0x00046384, 0x00000000, + 0x00000000, 0x00000880, 0xd6be4788, 0x002ec1e0, 0x002ec1e0, + 0x002ec1e0, 0x1883800a, 0x00000000, 0x0a1a9caa, 0x18010000, + 0x30032602, 0x48073e06, 0x560b4c0a, 0x641a600f, 0x7a4f6e1b, + 0x8c5b7e5a, 0x9d0f96cf, 0xb51fa69f, 0xcb3fbcbf, 0x0000d7bf, + 0x00000000, 0x00000000, 0x00000000 +}; + +static const uint32_t ar5416_vals_2g40[] = { + 0x000002c0, 0x00000318, 0x00007c70, 0x00016000, 0x10801600, + 0x12e013d7, 0x08f04810, 0x0000320a, 0x000003c4, 0x02020200, + 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x137216a0, + 0x00197a68, 0x00197a68, 0x00197a68, 0x6d48b0de, 0x7ec82d2e, + 0x3139605e, 0x00049d18, 0x0001ce00, 0x409a4190, 0x050cb081, + 0x00001130, 0x00000268, 0xd0058a0b, 0xffb81020, 0x00012d80, + 0x00012d80, 0x00012d80, 0x00001120, 0x001a0a00, 0x038919be, + 0x06336f77, 0x6af6532c, 0x08f186c8, 0x00046384, 0x00000000, + 0x00000000, 0x00000880, 0xd03e4788, 0x002ac120, 0x002ac120, + 0x002ac120, 0x1883800a, 0x00000210, 0x0a1a7caa, 0x18010000, + 0x2e032402, 0x4a0a3c06, 0x621a540b, 0x764f6c1b, 0x845b7a5a, + 0x950f8ccf, 0xa5cf9b4f, 0xbddfaf1f, 0xd1ffc93f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000 +}; + +static const uint32_t ar5416_vals_2g20[] = { + 0x00000160, 0x0000018c, 0x00003e38, 0x0000b000, 0x08400b00, + 0x12e013ab, 0x08f04810, 0x0000320a, 0x00000300, 0x02020200, + 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x137216a0, + 0x00197a68, 0x00197a68, 0x00197a68, 0x6c48b0de, 0x7ec82d2e, + 0x31395d5e, 0x00049d18, 0x0001ce00, 0x409a4190, 0x050cb081, + 0x00000898, 0x00000134, 0xd0058a0b, 0xffb81020, 0x00012d80, + 0x00012d80, 0x00012d80, 0x00001120, 0x001a0a00, 0x038919be, + 0x06336f77, 0x6af6532c, 0x08f186c8, 0x00046384, 0x00000000, + 0x00000000, 0x00000880, 0xd03e4788, 0x002ac120, 0x002ac120, + 0x002ac120, 0x1883800a, 0x00000108, 0x0a1a7caa, 0x18010000, + 0x2e032402, 0x4a0a3c06, 0x621a540b, 0x764f6c1b, 0x845b7a5a, + 0x950f8ccf, 0xa5cf9b4f, 0xbddfaf1f, 0xd1ffc93f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000 +}; + +static const uint16_t ar5416_cm_regs[] = { + P(0x0000c), P(0x00030), P(0x00034), P(0x00040), P(0x00044), + P(0x00048), P(0x0004c), P(0x00050), P(0x00054), P(0x00800), + P(0x00804), P(0x00808), P(0x0080c), P(0x00810), P(0x00814), + P(0x00818), P(0x0081c), P(0x00820), P(0x00824), P(0x01040), + P(0x01044), P(0x01048), P(0x0104c), P(0x01050), P(0x01054), + P(0x01058), P(0x0105c), P(0x01060), P(0x01064), P(0x01230), + P(0x01270), P(0x01038), P(0x01078), P(0x010b8), P(0x010f8), + P(0x01138), P(0x01178), P(0x011b8), P(0x011f8), P(0x01238), + P(0x01278), P(0x012b8), P(0x012f8), P(0x01338), P(0x01378), + P(0x013b8), P(0x013f8), P(0x01438), P(0x01478), P(0x014b8), + P(0x014f8), P(0x01538), P(0x01578), P(0x015b8), P(0x015f8), + P(0x01638), P(0x01678), P(0x016b8), P(0x016f8), P(0x01738), + P(0x01778), P(0x017b8), P(0x017f8), P(0x0103c), P(0x0107c), + P(0x010bc), P(0x010fc), P(0x0113c), P(0x0117c), P(0x011bc), + P(0x011fc), P(0x0123c), P(0x0127c), P(0x012bc), P(0x012fc), + P(0x0133c), P(0x0137c), P(0x013bc), P(0x013fc), P(0x0143c), + P(0x0147c), P(0x04030), P(0x0403c), P(0x07010), P(0x07038), + P(0x08004), P(0x08008), P(0x0800c), P(0x08018), P(0x08020), + P(0x08038), P(0x0803c), P(0x08048), P(0x08054), P(0x08058), + P(0x0805c), P(0x08060), P(0x08064), P(0x080c0), P(0x080c4), + P(0x080c8), P(0x080cc), P(0x080d0), P(0x080d4), P(0x080d8), + P(0x080e0), P(0x080e4), P(0x080e8), P(0x080ec), P(0x080f0), + P(0x080f4), P(0x080f8), P(0x080fc), P(0x08100), P(0x08104), + P(0x08108), P(0x0810c), P(0x08110), P(0x08118), P(0x0811c), + P(0x08124), P(0x08128), P(0x0812c), P(0x08130), P(0x08134), + P(0x08138), P(0x0813c), P(0x08144), P(0x08168), P(0x0816c), + P(0x08170), P(0x08174), P(0x08178), P(0x0817c), P(0x081c4), + P(0x081ec), P(0x081f0), P(0x081f4), P(0x081f8), P(0x081fc), + P(0x08200), P(0x08204), P(0x08208), P(0x0820c), P(0x08210), + P(0x08214), P(0x08218), P(0x0821c), P(0x08220), P(0x08224), + P(0x08228), P(0x0822c), P(0x08230), P(0x08234), P(0x08238), + P(0x0823c), P(0x08240), P(0x08244), P(0x08248), P(0x0824c), + P(0x08250), P(0x08254), P(0x08258), P(0x0825c), P(0x08260), + P(0x08264), P(0x08270), P(0x08274), P(0x08278), P(0x0827c), + P(0x08284), P(0x08288), P(0x0828c), P(0x08294), P(0x08298), + P(0x08300), P(0x08304), P(0x08308), P(0x0830c), P(0x08310), + P(0x08314), P(0x08318), P(0x08328), P(0x0832c), P(0x08330), + P(0x08334), P(0x08338), P(0x0833c), P(0x08340), P(0x09808), + P(0x0980c), P(0x09810), P(0x09814), P(0x0981c), P(0x0982c), + P(0x09830), P(0x0983c), P(0x09840), P(0x0984c), P(0x09854), + P(0x09900), P(0x09904), P(0x09908), P(0x0990c), P(0x0991c), + P(0x09920), P(0x0a920), P(0x0b920), P(0x09928), P(0x0992c), + P(0x09934), P(0x09938), P(0x0993c), P(0x09948), P(0x0994c), + P(0x09954), P(0x09958), P(0x0c95c), P(0x0c968), P(0x09970), + P(0x09974), P(0x09978), P(0x0997c), P(0x09980), P(0x09984), + P(0x09988), P(0x0998c), P(0x09990), P(0x09994), P(0x09998), + P(0x0999c), P(0x099a0), P(0x099a4), P(0x099a8), P(0x099ac), + P(0x099b0), P(0x099dc), P(0x099e0), P(0x099e4), P(0x099e8), + P(0x099ec), P(0x099fc), P(0x09b00), P(0x09b04), P(0x09b08), + P(0x09b0c), P(0x09b10), P(0x09b14), P(0x09b18), P(0x09b1c), + P(0x09b20), P(0x09b24), P(0x09b28), P(0x09b2c), P(0x09b30), + P(0x09b34), P(0x09b38), P(0x09b3c), P(0x09b40), P(0x09b44), + P(0x09b48), P(0x09b4c), P(0x09b50), P(0x09b54), P(0x09b58), + P(0x09b5c), P(0x09b60), P(0x09b64), P(0x09b68), P(0x09b6c), + P(0x09b70), P(0x09b74), P(0x09b78), P(0x09b7c), P(0x09b80), + P(0x09b84), P(0x09b88), P(0x09b8c), P(0x09b90), P(0x09b94), + P(0x09b98), P(0x09b9c), P(0x09ba0), P(0x09ba4), P(0x09ba8), + P(0x09bac), P(0x09bb0), P(0x09bb4), P(0x09bb8), P(0x09bbc), + P(0x09bc0), P(0x09bc4), P(0x09bc8), P(0x09bcc), P(0x09bd0), + P(0x09bd4), P(0x09bd8), P(0x09bdc), P(0x09be0), P(0x09be4), + P(0x09be8), P(0x09bec), P(0x09bf0), P(0x09bf4), P(0x09bf8), + P(0x09bfc), P(0x0a210), P(0x0a214), P(0x0a218), P(0x0a220), + P(0x0a224), P(0x0a228), P(0x0a22c), P(0x0a234), P(0x0a238), + P(0x0a23c), P(0x0a240), P(0x0a244), P(0x0a248), P(0x0a24c), + P(0x0a250), P(0x0a254), P(0x0a258), P(0x0a25c), P(0x0a260), + P(0x0a268), P(0x0a26c), P(0x0b26c), P(0x0c26c), P(0x0d270), + P(0x0a278), P(0x0a27c), P(0x0a338), P(0x0a33c), P(0x0a340), + P(0x0a344), P(0x0a348), P(0x0a34c), P(0x0a350), P(0x0a354), + P(0x0a358), P(0x0d35c), P(0x0d360), P(0x0d364), P(0x0d368), + P(0x0d36c), P(0x0d370), P(0x0d374), P(0x0d378), P(0x0d37c), + P(0x0d380), P(0x0d384), P(0x0a388), P(0x0a38c), P(0x0a390), + P(0x0a394), P(0x0a398), P(0x0a39c), P(0x0a3a0), P(0x0a3a4), + P(0x0a3a8), P(0x0a3ac), P(0x0a3b0), P(0x0a3b4), P(0x0a3b8), + P(0x0a3bc), P(0x0a3c0), P(0x0a3c4), P(0x0a3c8), P(0x0a3cc), + P(0x0a3d0), P(0x0a3d4), P(0x0a3dc), P(0x0a3e0) +}; + +static const uint32_t ar5416_cm_vals[] = { + 0x00000000, 0x00020015, 0x00000005, 0x00000000, 0x00000008, + 0x00000008, 0x00000010, 0x00000000, 0x0000001f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x002ffc0f, + 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, + 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x000004c2, + 0x00000000, 0x00000000, 0x00000000, 0x00000700, 0x00000000, + 0x00000000, 0x00000000, 0x40000000, 0x00000000, 0x00000000, + 0x000fc78f, 0x0000000f, 0x00000000, 0x2a82301a, 0x05dc01e0, + 0x1f402710, 0x01f40000, 0x00001e00, 0x00000000, 0x00400000, + 0xffffffff, 0x0000ffff, 0x003f3f3f, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00020000, 0x00020000, 0x00000001, + 0x00000052, 0x00000000, 0x00000168, 0x000100aa, 0x00003210, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, + 0x32143320, 0xfaa4fa50, 0x00000100, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00100000, 0x0010f400, 0x00000100, 0x0001e800, + 0x00000000, 0x00000000, 0x00000000, 0x400000ff, 0x00080922, + 0x88000010, 0x00000000, 0x40000000, 0x003e4180, 0x00000000, + 0x0000002c, 0x0000002c, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000302, + 0x00000e00, 0x00070000, 0x00000000, 0x000107ff, 0x00000000, + 0xad848e19, 0x7d14e000, 0x9c0a9f6b, 0x00000000, 0x0000a000, + 0x00000000, 0x00200400, 0x206a002e, 0x1284233c, 0x00000859, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x10000fff, + 0x05100000, 0x05100000, 0x05100000, 0x00000001, 0x00000004, + 0x1e1f2022, 0x0a0b0c0d, 0x00000000, 0x9280b212, 0x00020028, + 0x5d50e188, 0x00081fff, 0x004b6a8e, 0x000003ce, 0x190fb515, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x001fff00, 0x00000000, + 0x03051000, 0x00000000, 0x00000200, 0xaaaaaaaa, 0x3c466478, + 0x000000aa, 0x00001042, 0x00000000, 0x00000001, 0x00000002, + 0x00000003, 0x00000004, 0x00000005, 0x00000008, 0x00000009, + 0x0000000a, 0x0000000b, 0x0000000c, 0x0000000d, 0x00000010, + 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015, + 0x00000018, 0x00000019, 0x0000001a, 0x0000001b, 0x0000001c, + 0x0000001d, 0x00000020, 0x00000021, 0x00000022, 0x00000023, + 0x00000024, 0x00000025, 0x00000028, 0x00000029, 0x0000002a, + 0x0000002b, 0x0000002c, 0x0000002d, 0x00000030, 0x00000031, + 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000010, + 0x0000001a, 0x40806333, 0x00106c10, 0x009c4060, 0x018830c6, + 0x00000400, 0x00000bb5, 0x00000011, 0x20202020, 0x20202020, + 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc, 0x00000001, + 0x0000a000, 0x00000000, 0x0cc75380, 0x0f0f0f01, 0xdfa91f01, + 0x00000000, 0x0e79e5c6, 0x0e79e5c6, 0x0e79e5c6, 0x00820820, + 0x1ce739ce, 0x051701ce, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff, + 0x79a8aa1f, 0x07ffffef, 0x0fffffe7, 0x17ffffe5, 0x1fffffe4, + 0x37ffffe3, 0x3fffffe3, 0x57ffffe3, 0x5fffffe2, 0x7fffffe2, + 0x7f3c7bba, 0xf3307ff0, 0x08000000, 0x20202020, 0x20202020, + 0x1ce739ce, 0x000001ce, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000246, 0x20202020, + 0x20202020, 0x20202020, 0x1ce739ce, 0x000001ce +}; + +static const struct athn_ini ar5416_ini = { + nitems(ar5416_regs), + ar5416_regs, + ar5416_vals_5g20, + ar5416_vals_5g40, + ar5416_vals_2g40, + ar5416_vals_2g20, + nitems(ar5416_cm_regs), + ar5416_cm_regs, + ar5416_cm_vals +}; + +/* + * AR9160 initialization values. + */ +static const uint16_t ar9160_regs[] = { + P(0x01030), P(0x01070), P(0x010b0), P(0x010f0), P(0x08014), + P(0x0801c), P(0x08120), P(0x081d0), P(0x09804), P(0x09820), + P(0x09824), P(0x09828), P(0x09834), P(0x09838), P(0x09844), + P(0x09848), P(0x0a848), P(0x0b848), P(0x09850), P(0x09858), + P(0x0985c), P(0x09860), P(0x09864), P(0x09868), P(0x0986c), + P(0x09914), P(0x09918), P(0x09924), P(0x09944), P(0x09960), + P(0x0a960), P(0x0b960), P(0x09964), P(0x0c968), P(0x099bc), + P(0x099c0), P(0x099c4), P(0x099c8), P(0x099cc), P(0x099d0), + P(0x099d4), P(0x099d8), P(0x0a204), P(0x0a208), P(0x0a20c), + P(0x0b20c), P(0x0c20c), P(0x0a21c), P(0x0a230), P(0x0a274), + P(0x0a300), P(0x0a304), P(0x0a308), P(0x0a30c), P(0x0a310), + P(0x0a314), P(0x0a318), P(0x0a31c), P(0x0a320), P(0x0a324), + P(0x0a328), P(0x0a32c), P(0x0a330), P(0x0a334) +}; + +static const uint32_t ar9160_vals_5g20[] = { + 0x00000230, 0x00000168, 0x00000e60, 0x0000a000, 0x03e803e8, + 0x128d93a7, 0x08f04800, 0x00003210, 0x00000300, 0x02020200, + 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x0372161e, + 0x001a6a65, 0x001a6a65, 0x001a6a65, 0x6c48b4e2, 0x7ec82d2e, + 0x31395d5e, 0x00048d18, 0x0001ce00, 0x409a40d0, 0x050cb081, + 0x000007d0, 0x0000000a, 0xd00a8a07, 0xffb81020, 0x00009b40, + 0x00009b40, 0x00009b40, 0x00001120, 0x000003b5, 0x001a0600, + 0x038919be, 0x06336f77, 0x6af65329, 0x08f186c8, 0x00046384, + 0x00000000, 0x00000000, 0x00000880, 0xd6be4788, 0x002fc160, + 0x002fc160, 0x002fc160, 0x1883800a, 0x00000000, 0x0a1a9caa, + 0x18010000, 0x30032602, 0x48073e06, 0x560b4c0a, 0x641a600f, + 0x7a4f6e1b, 0x8c5b7e5a, 0x9d0f96cf, 0xb51fa69f, 0xcb3fbd07, + 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 +}; + +static const uint32_t ar9160_vals_5g40[] = { + 0x00000460, 0x000002d0, 0x00001cc0, 0x00014000, 0x07d007d0, + 0x128d93cf, 0x08f04800, 0x00003210, 0x000003c4, 0x02020200, + 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x0372161e, + 0x001a6a65, 0x001a6a65, 0x001a6a65, 0x6d48b4e2, 0x7ec82d2e, + 0x3139605e, 0x00048d18, 0x0001ce00, 0x409a40d0, 0x050cb081, + 0x00000fa0, 0x00000014, 0xd00a8a07, 0xffb81020, 0x00009b40, + 0x00009b40, 0x00009b40, 0x00001120, 0x000003b5, 0x001a0600, + 0x038919be, 0x06336f77, 0x6af65329, 0x08f186c8, 0x00046384, + 0x00000000, 0x00000000, 0x00000880, 0xd6be4788, 0x002fc160, + 0x002fc160, 0x002fc160, 0x1883800a, 0x00000000, 0x0a1a9caa, + 0x18010000, 0x30032602, 0x48073e06, 0x560b4c0a, 0x641a600f, + 0x7a4f6e1b, 0x8c5b7e5a, 0x9d0f96cf, 0xb51fa69f, 0xcb3fbcbf, + 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 +}; + +static const uint32_t ar9160_vals_2g40[] = { + 0x000002c0, 0x00000318, 0x00007c70, 0x00016000, 0x10801600, + 0x12e013d7, 0x08f04810, 0x0000320a, 0x000003c4, 0x02020200, + 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x037216a0, + 0x00197a68, 0x00197a68, 0x00197a68, 0x6d48b0e2, 0x7ec82d2e, + 0x3139605e, 0x00048d20, 0x0001ce00, 0x409a40d0, 0x050cb081, + 0x00001130, 0x00000016, 0xd00a8a0d, 0xffb81020, 0x00009b40, + 0x00009b40, 0x00009b40, 0x00001120, 0x000003ce, 0x001a0c00, + 0x038919be, 0x06336f77, 0x6af65329, 0x08f186c8, 0x00046384, + 0x00000000, 0x00000000, 0x00000880, 0xd03e4788, 0x002ac120, + 0x002ac120, 0x002ac120, 0x1883800a, 0x00000210, 0x0a1a7caa, + 0x18010000, 0x2e032402, 0x4a0a3c06, 0x621a540b, 0x764f6c1b, + 0x845b7a5a, 0x950f8ccf, 0xa5cf9b4f, 0xbddfaf1f, 0xd1ffc93f, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + +static const uint32_t ar9160_vals_2g20[] = { + 0x00000160, 0x0000018c, 0x00003e38, 0x0000b000, 0x08400b00, + 0x12e013ab, 0x08f04810, 0x0000320a, 0x00000300, 0x02020200, + 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x037216a0, + 0x00197a68, 0x00197a68, 0x00197a68, 0x6c48b0e2, 0x7ec82d2e, + 0x31395d5e, 0x00048d20, 0x0001ce00, 0x409a40d0, 0x050cb081, + 0x00000898, 0x0000000b, 0xd00a8a0d, 0xffb81020, 0x00009b40, + 0x00009b40, 0x00009b40, 0x00001120, 0x000003ce, 0x001a0c00, + 0x038919be, 0x06336f77, 0x6af65329, 0x08f186c8, 0x00046384, + 0x00000000, 0x00000000, 0x00000880, 0xd03e4788, 0x002ac120, + 0x002ac120, 0x002ac120, 0x1883800a, 0x00000108, 0x0a1a7caa, + 0x18010000, 0x2e032402, 0x4a0a3c06, 0x621a540b, 0x764f6c1b, + 0x845b7a5a, 0x950f8ccf, 0xa5cf9b4f, 0xbddfaf1f, 0xd1ffc93f, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + +static const uint16_t ar9160_cm_regs[] = { + P(0x0000c), P(0x00030), P(0x00034), P(0x00040), P(0x00044), + P(0x00048), P(0x0004c), P(0x00050), P(0x00054), P(0x00800), + P(0x00804), P(0x00808), P(0x0080c), P(0x00810), P(0x00814), + P(0x00818), P(0x0081c), P(0x00820), P(0x00824), P(0x01040), + P(0x01044), P(0x01048), P(0x0104c), P(0x01050), P(0x01054), + P(0x01058), P(0x0105c), P(0x01060), P(0x01064), P(0x01230), + P(0x01270), P(0x01038), P(0x01078), P(0x010b8), P(0x010f8), + P(0x01138), P(0x01178), P(0x011b8), P(0x011f8), P(0x01238), + P(0x01278), P(0x012b8), P(0x012f8), P(0x01338), P(0x01378), + P(0x013b8), P(0x013f8), P(0x01438), P(0x01478), P(0x014b8), + P(0x014f8), P(0x01538), P(0x01578), P(0x015b8), P(0x015f8), + P(0x01638), P(0x01678), P(0x016b8), P(0x016f8), P(0x01738), + P(0x01778), P(0x017b8), P(0x017f8), P(0x0103c), P(0x0107c), + P(0x010bc), P(0x010fc), P(0x0113c), P(0x0117c), P(0x011bc), + P(0x011fc), P(0x0123c), P(0x0127c), P(0x012bc), P(0x012fc), + P(0x0133c), P(0x0137c), P(0x013bc), P(0x013fc), P(0x0143c), + P(0x0147c), P(0x04030), P(0x0403c), P(0x07010), P(0x07038), + P(0x08004), P(0x08008), P(0x0800c), P(0x08018), P(0x08020), + P(0x08038), P(0x0803c), P(0x08048), P(0x08054), P(0x08058), + P(0x0805c), P(0x08060), P(0x08064), P(0x080c0), P(0x080c4), + P(0x080c8), P(0x080cc), P(0x080d0), P(0x080d4), P(0x080d8), + P(0x080e0), P(0x080e4), P(0x080e8), P(0x080ec), P(0x080f0), + P(0x080f4), P(0x080f8), P(0x080fc), P(0x08100), P(0x08104), + P(0x08108), P(0x0810c), P(0x08110), P(0x08118), P(0x0811c), + P(0x08124), P(0x08128), P(0x0812c), P(0x08130), P(0x08134), + P(0x08138), P(0x0813c), P(0x08144), P(0x08168), P(0x0816c), + P(0x08170), P(0x08174), P(0x08178), P(0x0817c), P(0x081c4), + P(0x081ec), P(0x081f0), P(0x081f4), P(0x081f8), P(0x081fc), + P(0x08200), P(0x08204), P(0x08208), P(0x0820c), P(0x08210), + P(0x08214), P(0x08218), P(0x0821c), P(0x08220), P(0x08224), + P(0x08228), P(0x0822c), P(0x08230), P(0x08234), P(0x08238), + P(0x0823c), P(0x08240), P(0x08244), P(0x08248), P(0x0824c), + P(0x08250), P(0x08254), P(0x08258), P(0x0825c), P(0x08260), + P(0x08264), P(0x08270), P(0x08274), P(0x08278), P(0x0827c), + P(0x08284), P(0x08288), P(0x0828c), P(0x08294), P(0x08298), + P(0x08300), P(0x08304), P(0x08308), P(0x0830c), P(0x08310), + P(0x08314), P(0x08318), P(0x08328), P(0x0832c), P(0x08330), + P(0x08334), P(0x08338), P(0x0833c), P(0x08340), P(0x09808), + P(0x0980c), P(0x09810), P(0x09814), P(0x0981c), P(0x0982c), + P(0x09830), P(0x0983c), P(0x09840), P(0x0984c), P(0x09854), + P(0x09900), P(0x09904), P(0x09908), P(0x0990c), P(0x0991c), + P(0x09920), P(0x0a920), P(0x0b920), P(0x09928), P(0x0992c), + P(0x09934), P(0x09938), P(0x0993c), P(0x09948), P(0x0994c), + P(0x09954), P(0x09958), P(0x09940), P(0x0c95c), P(0x09970), + P(0x09974), P(0x09978), P(0x0997c), P(0x09980), P(0x09984), + P(0x09988), P(0x0998c), P(0x09990), P(0x09994), P(0x09998), + P(0x0999c), P(0x099a0), P(0x099a4), P(0x099a8), P(0x099ac), + P(0x099b0), P(0x099dc), P(0x099e0), P(0x099e4), P(0x099e8), + P(0x099ec), P(0x099fc), P(0x09b00), P(0x09b04), P(0x09b08), + P(0x09b0c), P(0x09b10), P(0x09b14), P(0x09b18), P(0x09b1c), + P(0x09b20), P(0x09b24), P(0x09b28), P(0x09b2c), P(0x09b30), + P(0x09b34), P(0x09b38), P(0x09b3c), P(0x09b40), P(0x09b44), + P(0x09b48), P(0x09b4c), P(0x09b50), P(0x09b54), P(0x09b58), + P(0x09b5c), P(0x09b60), P(0x09b64), P(0x09b68), P(0x09b6c), + P(0x09b70), P(0x09b74), P(0x09b78), P(0x09b7c), P(0x09b80), + P(0x09b84), P(0x09b88), P(0x09b8c), P(0x09b90), P(0x09b94), + P(0x09b98), P(0x09b9c), P(0x09ba0), P(0x09ba4), P(0x09ba8), + P(0x09bac), P(0x09bb0), P(0x09bb4), P(0x09bb8), P(0x09bbc), + P(0x09bc0), P(0x09bc4), P(0x09bc8), P(0x09bcc), P(0x09bd0), + P(0x09bd4), P(0x09bd8), P(0x09bdc), P(0x09be0), P(0x09be4), + P(0x09be8), P(0x09bec), P(0x09bf0), P(0x09bf4), P(0x09bf8), + P(0x09bfc), P(0x0a210), P(0x0a214), P(0x0a218), P(0x0a220), + P(0x0a224), P(0x0a228), P(0x0a22c), P(0x0a234), P(0x0a238), + P(0x0a23c), P(0x0a240), P(0x0a244), P(0x0a248), P(0x0a24c), + P(0x0a250), P(0x0a254), P(0x0a258), P(0x0a25c), P(0x0a260), + P(0x0a268), P(0x0a26c), P(0x0b26c), P(0x0c26c), P(0x0d270), + P(0x0a278), P(0x0a27c), P(0x0a338), P(0x0a33c), P(0x0a340), + P(0x0a344), P(0x0a348), P(0x0a34c), P(0x0a350), P(0x0a354), + P(0x0a358), P(0x0d35c), P(0x0d360), P(0x0d364), P(0x0d368), + P(0x0d36c), P(0x0d370), P(0x0d374), P(0x0d378), P(0x0d37c), + P(0x0d380), P(0x0d384), P(0x0a388), P(0x0a38c), P(0x0a390), + P(0x0a394), P(0x0a398), P(0x0a39c), P(0x0a3a0), P(0x0a3a4), + P(0x0a3a8), P(0x0a3ac), P(0x0a3b0), P(0x0a3b4), P(0x0a3b8), + P(0x0a3bc), P(0x0a3c0), P(0x0a3c4), P(0x0a3c8), P(0x0a3cc), + P(0x0a3d0), P(0x0a3d4), P(0x0a3dc), P(0x0a3e0) +}; + +static const uint32_t ar9160_cm_vals[] = { + 0x00000000, 0x00020015, 0x00000005, 0x00000000, 0x00000008, + 0x00000008, 0x00000010, 0x00000000, 0x0000001f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x002ffc0f, + 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, + 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x00000002, 0x00000020, 0x000004c2, + 0x00000000, 0x00000000, 0x00000000, 0x00000700, 0x00000000, + 0x00000000, 0x00000000, 0x40000000, 0x00000000, 0x00000000, + 0x000fc78f, 0x0000000f, 0x00000000, 0x2a82301a, 0x05dc01e0, + 0x1f402710, 0x01f40000, 0x00001e00, 0x00000000, 0x00400000, + 0xffffffff, 0x0000ffff, 0x003f3f3f, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00020000, 0x00020000, 0x00000001, + 0x00000052, 0x00000000, 0x00000168, 0x000100aa, 0x00003210, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, + 0x32143320, 0xfaa4fa50, 0x00000100, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00100000, 0x0010f400, 0x00000100, 0x0001e800, + 0x00000000, 0x00000000, 0x00000000, 0x400000ff, 0x00080922, + 0x88a00010, 0x00000000, 0x40000000, 0x003e4180, 0x00000000, + 0x0000002c, 0x0000002c, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000302, + 0x00000e00, 0x00ff0000, 0x00000000, 0x000107ff, 0x00000000, + 0xad848e19, 0x7d14e000, 0x9c0a9f6b, 0x00000000, 0x0000a000, + 0x00000000, 0x00200400, 0x206a01ae, 0x1284233c, 0x00000859, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x10000fff, + 0x05100000, 0x05100000, 0x05100000, 0x00000001, 0x00000004, + 0x1e1f2022, 0x0a0b0c0d, 0x00000000, 0x9280b212, 0x00020028, + 0x5f3ca3de, 0x2108ecff, 0x00750604, 0x004b6a8e, 0x190fb515, + 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x201fff00, 0x006f0000, + 0x03051000, 0x00000000, 0x00000200, 0xaaaaaaaa, 0x3c466478, + 0x0cc80caa, 0x00001042, 0x00000000, 0x00000001, 0x00000002, + 0x00000003, 0x00000004, 0x00000005, 0x00000008, 0x00000009, + 0x0000000a, 0x0000000b, 0x0000000c, 0x0000000d, 0x00000010, + 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015, + 0x00000018, 0x00000019, 0x0000001a, 0x0000001b, 0x0000001c, + 0x0000001d, 0x00000020, 0x00000021, 0x00000022, 0x00000023, + 0x00000024, 0x00000025, 0x00000028, 0x00000029, 0x0000002a, + 0x0000002b, 0x0000002c, 0x0000002d, 0x00000030, 0x00000031, + 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035, + 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000010, + 0x0000001a, 0x40806333, 0x00106c10, 0x009c4060, 0x018830c6, + 0x00000400, 0x001a0bb5, 0x00000000, 0x20202020, 0x20202020, + 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc, 0x00000001, + 0x0000e000, 0x00000000, 0x0cc75380, 0x0f0f0f01, 0xdfa91f01, + 0x00000001, 0x0e79e5c6, 0x0e79e5c6, 0x0e79e5c6, 0x00820820, + 0x1ce739ce, 0x050701ce, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff, + 0x79bfaa03, 0x07ffffef, 0x0fffffe7, 0x17ffffe5, 0x1fffffe4, + 0x37ffffe3, 0x3fffffe3, 0x57ffffe3, 0x5fffffe2, 0x7fffffe2, + 0x7f3c7bba, 0xf3307ff0, 0x0c000000, 0x20202020, 0x20202020, + 0x1ce739ce, 0x000001ce, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000246, 0x20202020, + 0x20202020, 0x20202020, 0x1ce739ce, 0x000001ce +}; + +static const struct athn_ini ar9160_ini = { + nitems(ar9160_regs), + ar9160_regs, + ar9160_vals_5g20, + ar9160_vals_5g40, + ar9160_vals_2g40, + ar9160_vals_2g20, + nitems(ar9160_cm_regs), + ar9160_cm_regs, + ar9160_cm_vals +}; + +/* + * BB/RF Gains common to AR5416 and AR9160. + */ +static const uint32_t ar5416_bb_rfgain_vals_5g[] = { + 0x00000000, 0x00000040, 0x00000080, 0x000001a1, 0x000001e1, + 0x00000021, 0x00000061, 0x00000168, 0x000001a8, 0x000001e8, + 0x00000028, 0x00000068, 0x00000189, 0x000001c9, 0x00000009, + 0x00000049, 0x00000089, 0x00000170, 0x000001b0, 0x000001f0, + 0x00000030, 0x00000070, 0x00000191, 0x000001d1, 0x00000011, + 0x00000051, 0x00000091, 0x000001b8, 0x000001f8, 0x00000038, + 0x00000078, 0x00000199, 0x000001d9, 0x00000019, 0x00000059, + 0x00000099, 0x000000d9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9 +}; + +static const uint32_t ar5416_bb_rfgain_vals_2g[] = { + 0x00000000, 0x00000040, 0x00000080, 0x00000141, 0x00000181, + 0x000001c1, 0x00000001, 0x00000041, 0x000001a8, 0x000001e8, + 0x00000028, 0x00000068, 0x000000a8, 0x00000169, 0x000001a9, + 0x000001e9, 0x00000029, 0x00000069, 0x00000190, 0x000001d0, + 0x00000010, 0x00000050, 0x00000090, 0x00000151, 0x00000191, + 0x000001d1, 0x00000011, 0x00000051, 0x00000198, 0x000001d8, + 0x00000018, 0x00000058, 0x00000098, 0x00000159, 0x00000199, + 0x000001d9, 0x00000019, 0x00000059, 0x00000099, 0x000000d9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, + 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9 +}; + +static const uint32_t ar5416_2_1_addac_vals[] = { + 0x00000000, 0x00000003, 0x00000000, 0x0000000c, 0x00000000, + 0x00000030, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000060, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000 +}; + +static const struct athn_addac ar5416_2_1_addac = { + nitems(ar5416_2_1_addac_vals), + ar5416_2_1_addac_vals +}; + +static const uint32_t ar5416_2_2_addac_vals[] = { + 0x00000000, 0x00000003, 0x00000000, 0x0000000c, 0x00000000, + 0x00000030, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000060, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000058, 0x00000000, 0x00000000, 0x00000000, + 0x00000000 +}; + +static const struct athn_addac ar5416_2_2_addac = { + nitems(ar5416_2_2_addac_vals), + ar5416_2_2_addac_vals +}; + +static const uint32_t ar9160_1_0_addac_vals[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000000c0, 0x00000018, 0x00000004, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000000c0, 0x00000019, 0x00000004, 0x00000000, + 0x00000000, 0x00000000, 0x00000004, 0x00000003, 0x00000008, + 0x00000000 +}; + +static const struct athn_addac ar9160_1_0_addac = { + nitems(ar9160_1_0_addac_vals), + ar9160_1_0_addac_vals +}; + +static const uint32_t ar9160_1_1_addac_vals[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000000c0, 0x00000018, 0x00000004, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000000c0, 0x00000019, 0x00000004, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000 +}; + +static const struct athn_addac ar9160_1_1_addac = { + nitems(ar9160_1_1_addac_vals), + ar9160_1_1_addac_vals +}; + +static const uint32_t ar5416_bank6tpc_vals[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00e00000, 0x005e0000, + 0x00120000, 0x00620000, 0x00020000, 0x00ff0000, 0x00ff0000, + 0x00ff0000, 0x40ff0000, 0x005f0000, 0x00870000, 0x00f90000, + 0x007b0000, 0x00ff0000, 0x00f50000, 0x00dc0000, 0x00110000, + 0x006100a8, 0x00423022, 0x201400df, 0x00c40002, 0x003000f2, + 0x00440016, 0x00410040, 0x0001805e, 0x0000c0ab, 0x000000e1, + 0x00007081, 0x000000d4 +}; + +static const uint32_t ar9160_bank6tpc_vals[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00e00000, 0x005e0000, + 0x00120000, 0x00620000, 0x00020000, 0x00ff0000, 0x00ff0000, + 0x00ff0000, 0x40ff0000, 0x005f0000, 0x00870000, 0x00f90000, + 0x007b0000, 0x00ff0000, 0x00f50000, 0x00dc0000, 0x00110000, + 0x006100a8, 0x00423022, 0x2014008f, 0x00c40002, 0x003000f2, + 0x00440016, 0x00410040, 0x0001805e, 0x0000c0ab, 0x000000e1, + 0x00007080, 0x000000d4 +}; + +static const uint32_t ar5416_bank6_vals[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00e00000, 0x005e0000, + 0x00120000, 0x00620000, 0x00020000, 0x00ff0000, 0x00ff0000, + 0x00ff0000, 0x40ff0000, 0x005f0000, 0x00870000, 0x00f90000, + 0x007b0000, 0x00ff0000, 0x00f50000, 0x00dc0000, 0x00110000, + 0x006100a8, 0x004210a2, 0x0014008f, 0x00c40003, 0x003000f2, + 0x00440016, 0x00410040, 0x0001805e, 0x0000c0ab, 0x000000f1, + 0x00002081, 0x000000d4 +}; + +/* + * Serializer/Deserializer programming. + */ + +static const uint32_t ar5416_serdes_regs[] = { + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES2 +}; + +static const uint32_t ar5416_serdes_vals[] = { + 0x9248fc00, + 0x24924924, + /* RX shut off when elecidle is asserted. */ + 0x28000039, + 0x53160824, + 0xe5980579, + 0x001defff, + 0x1aaabe40, + 0xbe105554, + 0x000e3007, + 0x00000000 +}; + +static const struct athn_serdes ar5416_serdes = { + nitems(ar5416_serdes_vals), + ar5416_serdes_regs, + ar5416_serdes_vals, +}; diff --git a/sys/dev/athn/headers/ar9280reg.h b/sys/dev/athn/headers/ar9280reg.h new file mode 100644 --- /dev/null +++ b/sys/dev/athn/headers/ar9280reg.h @@ -0,0 +1,620 @@ +/* $OpenBSD: ar9280reg.h,v 1.8 2019/02/01 16:15:07 stsp Exp $ */ + +/*- + * Copyright (c) 2009 Damien Bergamini + * Copyright (c) 2008-2009 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define AR9280_MAX_CHAINS 2 + +#define AR9280_PD_GAIN_BOUNDARY_DEFAULT 56 + +#define AR9280_PHY_CCA_MIN_GOOD_VAL_2GHZ (-127) +#define AR9280_PHY_CCA_MIN_GOOD_VAL_5GHZ (-122) +#define AR9280_PHY_CCA_MAX_GOOD_VAL_2GHZ (-97) +#define AR9280_PHY_CCA_MAX_GOOD_VAL_5GHZ (-102) + +#define AR9280_PHY_SYNTH_CONTROL 0x9874 + +/* Bits for AR9280_PHY_SYNTH_CONTROL. */ +#define AR9280_BMODE 0x20000000 +#define AR9280_FRACMODE 0x10000000 +#define AR9280_AMODE_REFSEL_M 0x0c000000 +#define AR9280_AMODE_REFSEL_S 26 + +/* + * NB: The AR9280 uses the same ROM layout than the AR5416. + */ + +/* Macro to "pack" registers to 16-bit to save some .rodata space. */ +#define P(x) (x) + +/* + * AR9280 2.0 initialization values. + */ +static const uint16_t ar9280_2_0_regs[] = { + P(0x01030), P(0x01070), P(0x010b0), P(0x010f0), P(0x08014), + P(0x0801c), P(0x08120), P(0x081d0), P(0x08318), P(0x09804), + P(0x09820), P(0x09824), P(0x09828), P(0x09834), P(0x09838), + P(0x09840), P(0x09844), P(0x09850), P(0x09858), P(0x0985c), + P(0x09860), P(0x09864), P(0x09868), P(0x0986c), P(0x09914), + P(0x09918), P(0x09924), P(0x09944), P(0x09960), P(0x0a960), + P(0x09964), P(0x0c968), P(0x099b8), P(0x099bc), P(0x099c0), + P(0x0a204), P(0x0a20c), P(0x0b20c), P(0x0a21c), P(0x0a230), + P(0x0a23c), P(0x0a250), P(0x0a358), P(0x0a388), P(0x0a3d8), + P(0x07894) +}; + +static const uint32_t ar9280_2_0_vals_5g20[] = { + 0x00000230, 0x00000168, 0x00000e60, 0x00000000, 0x03e803e8, + 0x128d8027, 0x08f04800, 0x00003210, 0x00003e80, 0x00000300, + 0x02020200, 0x01000e0e, 0x0a020001, 0x00000e0e, 0x00000007, + 0x206a022e, 0x0372161e, 0x6c4000e2, 0x7ec88d2e, 0x31395d5e, + 0x00048d18, 0x0001ce00, 0x5ac640d0, 0x06903081, 0x000007d0, + 0x0000000a, 0xd00a8a0b, 0xffbc1010, 0x00000010, 0x00000010, + 0x00000210, 0x000003b5, 0x0000001c, 0x00000a00, 0x05eea6d4, + 0x00000444, 0x00000014, 0x00000014, 0x1883800a, 0x00000000, + 0x13c88000, 0x001ff000, 0x7999aa02, 0x0c000000, 0x00000000, + 0x5a508000 +}; + +static const uint32_t ar9280_2_0_vals_5g40[] = { + 0x00000460, 0x000002d0, 0x00001cc0, 0x00000000, 0x07d007d0, + 0x128d804f, 0x08f04800, 0x00003210, 0x00007d00, 0x000003c4, + 0x02020200, 0x01000e0e, 0x0a020001, 0x00000e0e, 0x00000007, + 0x206a022e, 0x0372161e, 0x6d4000e2, 0x7ec88d2e, 0x3139605e, + 0x00048d18, 0x0001ce00, 0x5ac640d0, 0x06903081, 0x00000fa0, + 0x00000014, 0xd00a8a0b, 0xffbc1010, 0x00000010, 0x00000010, + 0x00000210, 0x000003b5, 0x0000001c, 0x00000a00, 0x05eea6d4, + 0x00000444, 0x00000014, 0x00000014, 0x1883800a, 0x00000000, + 0x13c88000, 0x001ff000, 0x7999aa02, 0x0c000000, 0x00000000, + 0x5a508000 +}; + +static const uint32_t ar9280_2_0_vals_2g40[] = { + 0x000002c0, 0x00000318, 0x00007c70, 0x00000000, 0x10801600, + 0x12e00057, 0x08f04810, 0x0000320a, 0x00006880, 0x000003c4, + 0x02020200, 0x01000e0e, 0x0a020001, 0x00000e0e, 0x00000007, + 0x206a012e, 0x037216a0, 0x6d4000e2, 0x7ec84d2e, 0x3139605e, + 0x00048d20, 0x0001ce00, 0x5ac640d0, 0x06903881, 0x00001130, + 0x00000268, 0xd00a8a0d, 0xffbc1010, 0x00000010, 0x00000010, + 0x00000210, 0x000003ce, 0x0000001c, 0x00000c00, 0x05eea6d4, + 0x00000444, 0x0001f019, 0x0001f019, 0x1883800a, 0x00000210, + 0x13c88001, 0x0004a000, 0x7999aa0e, 0x08000000, 0x00000000, + 0x5a508000 +}; + +static const uint32_t ar9280_2_0_vals_2g20[] = { + 0x00000160, 0x0000018c, 0x00003e38, 0x00000000, 0x08400b00, + 0x12e0002b, 0x08f04810, 0x0000320a, 0x00003440, 0x00000300, + 0x02020200, 0x01000e0e, 0x0a020001, 0x00000e0e, 0x00000007, + 0x206a012e, 0x037216a0, 0x6c4000e2, 0x7ec84d2e, 0x31395d5e, + 0x00048d20, 0x0001ce00, 0x5ac640d0, 0x06903881, 0x00000898, + 0x0000000b, 0xd00a8a0d, 0xffbc1010, 0x00000010, 0x00000010, + 0x00000210, 0x000003ce, 0x0000001c, 0x00000c00, 0x05eea6d4, + 0x00000444, 0x0001f019, 0x0001f019, 0x1883800a, 0x00000108, + 0x13c88000, 0x0004a000, 0x7999aa0e, 0x0c000000, 0x00000000, + 0x5a508000 +}; + +static const uint16_t ar9280_2_0_cm_regs[] = { + P(0x0000c), P(0x00030), P(0x00034), P(0x00040), P(0x00044), + P(0x00048), P(0x0004c), P(0x00050), P(0x00054), P(0x00800), + P(0x00804), P(0x00808), P(0x0080c), P(0x00810), P(0x00814), + P(0x00818), P(0x0081c), P(0x00820), P(0x00824), P(0x01040), + P(0x01044), P(0x01048), P(0x0104c), P(0x01050), P(0x01054), + P(0x01058), P(0x0105c), P(0x01060), P(0x01064), P(0x01230), + P(0x01270), P(0x01038), P(0x01078), P(0x010b8), P(0x010f8), + P(0x01138), P(0x01178), P(0x011b8), P(0x011f8), P(0x01238), + P(0x01278), P(0x012b8), P(0x012f8), P(0x01338), P(0x01378), + P(0x013b8), P(0x013f8), P(0x01438), P(0x01478), P(0x014b8), + P(0x014f8), P(0x01538), P(0x01578), P(0x015b8), P(0x015f8), + P(0x01638), P(0x01678), P(0x016b8), P(0x016f8), P(0x01738), + P(0x01778), P(0x017b8), P(0x017f8), P(0x0103c), P(0x0107c), + P(0x010bc), P(0x010fc), P(0x0113c), P(0x0117c), P(0x011bc), + P(0x011fc), P(0x0123c), P(0x0127c), P(0x012bc), P(0x012fc), + P(0x0133c), P(0x0137c), P(0x013bc), P(0x013fc), P(0x0143c), + P(0x0147c), P(0x04030), P(0x0403c), P(0x04024), P(0x04060), + P(0x04064), P(0x07010), P(0x07034), P(0x07038), P(0x08004), + P(0x08008), P(0x0800c), P(0x08018), P(0x08020), P(0x08038), + P(0x0803c), P(0x08048), P(0x08054), P(0x08058), P(0x0805c), + P(0x08060), P(0x08064), P(0x08070), P(0x080c0), P(0x080c4), + P(0x080c8), P(0x080cc), P(0x080d0), P(0x080d4), P(0x080d8), + P(0x080e0), P(0x080e4), P(0x080e8), P(0x080ec), P(0x080f0), + P(0x080f4), P(0x080f8), P(0x080fc), P(0x08100), P(0x08104), + P(0x08108), P(0x0810c), P(0x08110), P(0x08118), P(0x0811c), + P(0x08124), P(0x08128), P(0x0812c), P(0x08130), P(0x08134), + P(0x08138), P(0x0813c), P(0x08144), P(0x08168), P(0x0816c), + P(0x08170), P(0x08174), P(0x08178), P(0x0817c), P(0x081c0), + P(0x081ec), P(0x081f0), P(0x081f4), P(0x081f8), P(0x081fc), + P(0x08200), P(0x08204), P(0x08208), P(0x0820c), P(0x08210), + P(0x08214), P(0x08218), P(0x0821c), P(0x08220), P(0x08224), + P(0x08228), P(0x0822c), P(0x08230), P(0x08234), P(0x08238), + P(0x0823c), P(0x08240), P(0x08244), P(0x08248), P(0x0824c), + P(0x08250), P(0x08254), P(0x08258), P(0x0825c), P(0x08260), + P(0x08264), P(0x08270), P(0x08274), P(0x08278), P(0x0827c), + P(0x08284), P(0x08288), P(0x0828c), P(0x08294), P(0x08298), + P(0x0829c), P(0x08300), P(0x08314), P(0x08328), P(0x0832c), + P(0x08330), P(0x08334), P(0x08338), P(0x0833c), P(0x08340), + P(0x08344), P(0x09808), P(0x0980c), P(0x09810), P(0x09814), + P(0x0981c), P(0x0982c), P(0x09830), P(0x0983c), P(0x0984c), + P(0x0a84c), P(0x09854), P(0x09900), P(0x09904), P(0x09908), + P(0x0990c), P(0x09910), P(0x0991c), P(0x09920), P(0x0a920), + P(0x09928), P(0x0992c), P(0x09934), P(0x09938), P(0x0993c), + P(0x09948), P(0x0994c), P(0x09954), P(0x09958), P(0x09940), + P(0x0c95c), P(0x09970), P(0x09974), P(0x09978), P(0x0997c), + P(0x09980), P(0x09984), P(0x09988), P(0x0998c), P(0x09990), + P(0x09994), P(0x09998), P(0x0999c), P(0x099a0), P(0x099a4), + P(0x099a8), P(0x099ac), P(0x099b0), P(0x099b4), P(0x099c4), + P(0x099c8), P(0x099cc), P(0x099d0), P(0x099d4), P(0x099d8), + P(0x099dc), P(0x099e0), P(0x099e4), P(0x099e8), P(0x099ec), + P(0x099f0), P(0x099fc), P(0x0a208), P(0x0a210), P(0x0a214), + P(0x0a218), P(0x0a220), P(0x0a224), P(0x0a228), P(0x0a22c), + P(0x0a234), P(0x0a238), P(0x0a240), P(0x0a244), P(0x0a248), + P(0x0a24c), P(0x0a254), P(0x0a258), P(0x0a25c), P(0x0a260), + P(0x0a268), P(0x0a26c), P(0x0b26c), P(0x0d270), P(0x0a278), + P(0x0d35c), P(0x0d360), P(0x0d364), P(0x0d368), P(0x0d36c), + P(0x0d370), P(0x0d374), P(0x0d378), P(0x0d37c), P(0x0d380), + P(0x0d384), P(0x0a38c), P(0x0a390), P(0x0a394), P(0x0a398), + P(0x0a39c), P(0x0a3a0), P(0x0a3a4), P(0x0a3a8), P(0x0a3ac), + P(0x0a3b0), P(0x0a3b4), P(0x0a3b8), P(0x0a3bc), P(0x0a3c0), + P(0x0a3c4), P(0x0a3c8), P(0x0a3cc), P(0x0a3d0), P(0x0a3d4), + P(0x0a3dc), P(0x0a3e0), P(0x0a3e4), P(0x0a3e8), P(0x07800), + P(0x07804), P(0x07808), P(0x0780c), P(0x07810), P(0x07818), + P(0x07824), P(0x07828), P(0x0782c), P(0x07830), P(0x07834), + P(0x0783c), P(0x07848), P(0x0784c), P(0x07850), P(0x07854), + P(0x07858), P(0x07860), P(0x07864), P(0x07868), P(0x0786c), + P(0x07870), P(0x07874), P(0x07878), P(0x0787c), P(0x07880), + P(0x07884), P(0x07888), P(0x0788c), P(0x07890), P(0x07898) +}; + +static const uint32_t ar9280_2_0_cm_vals[] = { + 0x00000000, 0x00020015, 0x00000005, 0x00000000, 0x00000008, + 0x00000008, 0x00000010, 0x00000000, 0x0000001f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x002ffc0f, + 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, + 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x00000002, 0x0000001f, 0x00000000, + 0x00000000, 0x00000033, 0x00000002, 0x000004c2, 0x00000000, + 0x00000000, 0x00000000, 0x00000700, 0x00000000, 0x00000000, + 0x00000000, 0x40000000, 0x00000000, 0x00000000, 0x000fc78f, + 0x0000000f, 0x00000000, 0x00000000, 0x2a80001a, 0x05dc01e0, + 0x1f402710, 0x01f40000, 0x00001e00, 0x00000000, 0x00400000, + 0xffffffff, 0x0000ffff, 0x003f3f3f, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00020000, 0x00020000, 0x00000001, + 0x00000052, 0x00000000, 0x00000168, 0x000100aa, 0x00003210, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, + 0x32143320, 0xfaa4fa50, 0x00000100, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00100000, 0x0010f400, 0x00000100, 0x0001e800, + 0x00000000, 0x00000000, 0x00000000, 0x400000ff, 0x00080922, + 0x88a00010, 0x00000000, 0x40000000, 0x003e4180, 0x00000000, + 0x0000002c, 0x0000002c, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000040, 0x00000000, 0x00000000, 0x00000007, + 0x00000302, 0x00000e00, 0x00ff0000, 0x00000000, 0x000107ff, + 0x00481043, 0x00000000, 0xafa68e30, 0xfd14e000, 0x9c0a9f6b, + 0x00000000, 0x0000a000, 0x00000000, 0x00200400, 0x0040233c, + 0x0040233c, 0x00000044, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x01002310, 0x10000fff, 0x04900000, 0x04900000, + 0x00000001, 0x00000004, 0x1e1f2022, 0x0a0b0c0d, 0x00000000, + 0x9280c00a, 0x00020028, 0x5f3ca3de, 0x2108ecff, 0x14750604, + 0x004b6a8e, 0x190fb514, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x201fff00, 0x006f0000, 0x03051000, 0x00000820, 0x06336f77, + 0x6af6532f, 0x08f186c8, 0x00046384, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xaaaaaaaa, 0x3c466478, 0x0cc80caa, + 0x00000000, 0x00001042, 0x803e4788, 0x4080a333, 0x40206c10, + 0x009c4060, 0x01834061, 0x00000400, 0x000003b5, 0x233f7180, + 0x20202020, 0x20202020, 0x38490a20, 0x00007bb6, 0x0fff3ffc, + 0x00000000, 0x00000000, 0x0cdbd380, 0x0f0f0f01, 0xdfa91f01, + 0x00000000, 0x0e79e5c6, 0x0e79e5c6, 0x00820820, 0x1ce739ce, + 0x07ffffef, 0x0fffffe7, 0x17ffffe5, 0x1fffffe4, 0x37ffffe3, + 0x3fffffe3, 0x57ffffe3, 0x5fffffe2, 0x7fffffe2, 0x7f3c7bba, + 0xf3307ff0, 0x20202020, 0x20202020, 0x1ce739ce, 0x000001ce, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000246, 0x20202020, 0x20202020, 0x20202020, + 0x1ce739ce, 0x000001ce, 0x00000000, 0x18c43433, 0x00040000, + 0xdb005012, 0x04924914, 0x21084210, 0x6d801300, 0x07e41000, + 0x00040000, 0xdb005012, 0x04924914, 0x21084210, 0x6d801300, + 0x07e40000, 0x00100000, 0x773f0567, 0x54214514, 0x12035828, + 0x9259269a, 0x52802000, 0x0a8e370e, 0xc0102850, 0x812d4000, + 0x807ec400, 0x001b6db0, 0x00376b63, 0x06db6db6, 0x006d8000, + 0xffeffffe, 0xffeffffe, 0x00010000, 0x02060aeb, 0x2a850160 +}; + +static const uint16_t ar9280_2_0_fast_clock_regs[] = { + P(0x01030), P(0x01070), P(0x010b0), P(0x08014), P(0x0801c), + P(0x08318), P(0x09820), P(0x09824), P(0x09828), P(0x09834), + P(0x09844), P(0x09914), P(0x09918) +}; + +static const uint32_t ar9280_2_0_fast_clock_vals_5g20[] = { + 0x00000268, 0x0000018c, 0x00000fd0, 0x044c044c, 0x148ec02b, + 0x000044c0, 0x02020200, 0x01000f0f, 0x0b020001, 0x00000f0f, + 0x03721821, 0x00000898, 0x0000000b +}; + +static const uint32_t ar9280_2_0_fast_clock_vals_5g40[] = { + 0x000004d0, 0x00000318, 0x00001fa0, 0x08980898, 0x148ec057, + 0x00008980, 0x02020200, 0x01000f0f, 0x0b020001, 0x00000f0f, + 0x03721821, 0x00001130, 0x00000016 +}; + +static const struct athn_ini ar9280_2_0_ini = { + nitems(ar9280_2_0_regs), + ar9280_2_0_regs, + ar9280_2_0_vals_5g20, + ar9280_2_0_vals_5g40, + ar9280_2_0_vals_2g40, + ar9280_2_0_vals_2g20, + nitems(ar9280_2_0_cm_regs), + ar9280_2_0_cm_regs, + ar9280_2_0_cm_vals, + nitems(ar9280_2_0_fast_clock_regs), + ar9280_2_0_fast_clock_regs, + ar9280_2_0_fast_clock_vals_5g20, + ar9280_2_0_fast_clock_vals_5g40 +}; + +/* + * AR9280 2.0 Tx gains. + */ +static const uint16_t ar9280_2_0_tx_gain_regs[] = { + P(0x0a274), P(0x0a27c), P(0x0a300), P(0x0a304), P(0x0a308), + P(0x0a30c), P(0x0a310), P(0x0a314), P(0x0a318), P(0x0a31c), + P(0x0a320), P(0x0a324), P(0x0a328), P(0x0a32c), P(0x0a330), + P(0x0a334), P(0x0a338), P(0x0a33c), P(0x0a340), P(0x0a344), + P(0x0a348), P(0x0a34c), P(0x0a350), P(0x0a354), P(0x0a3ec), + P(0x07814), P(0x07838), P(0x0781c), P(0x07840), P(0x07820), + P(0x07844) +}; + +static const uint32_t ar9280_2_0_tx_gain_vals_5g[] = { + 0x0a19c652, 0x050701ce, 0x00000000, 0x00003002, 0x00006004, + 0x0000a006, 0x0000e012, 0x00011014, 0x0001504a, 0x0001904c, + 0x0001c04e, 0x00020092, 0x0002410a, 0x0002710c, 0x0002b18b, + 0x0002e1cc, 0x000321ec, 0x000321ec, 0x000321ec, 0x000321ec, + 0x000321ec, 0x000321ec, 0x000321ec, 0x000321ec, 0x00f70081, + 0x0019beff, 0x0019beff, 0x00392000, 0x00392000, 0x92592480, + 0x92592480 +}; + +static const uint32_t ar9280_2_0_tx_gain_vals_2g[] = { + 0x0a1aa652, 0x050701ce, 0x00000000, 0x00003002, 0x00008009, + 0x0000b00b, 0x0000e012, 0x00012048, 0x0001604a, 0x0001a211, + 0x0001e213, 0x0002121b, 0x00024412, 0x00028414, 0x0002b44a, + 0x00030649, 0x0003364b, 0x00038a49, 0x0003be48, 0x0003ee4a, + 0x00042e88, 0x00046e8a, 0x00049ec9, 0x0004bf42, 0x00f70081, + 0x0019beff, 0x0019beff, 0x00392000, 0x00392000, 0x92592480, + 0x92592480 +}; + +static const struct athn_gain ar9280_2_0_tx_gain = { + nitems(ar9280_2_0_tx_gain_regs), + ar9280_2_0_tx_gain_regs, + ar9280_2_0_tx_gain_vals_5g, + ar9280_2_0_tx_gain_vals_2g +}; + +static const uint32_t ar9280_2_0_tx_gain_high_power_vals_5g[] = { + 0x0a19e652, 0x050739ce, 0x00000000, 0x00003002, 0x00006004, + 0x0000a006, 0x0000e012, 0x00011014, 0x0001504a, 0x0001904c, + 0x0001c04e, 0x00021092, 0x0002510a, 0x0002910c, 0x0002c18b, + 0x0002f1cc, 0x000321eb, 0x000341ec, 0x000341ec, 0x000341ec, + 0x000341ec, 0x000341ec, 0x000341ec, 0x000341ec, 0x00f70081, + 0x00198eff, 0x00198eff, 0x00172000, 0x00172000, 0xf258a480, + 0xf258a480 +}; + +static const uint32_t ar9280_2_0_tx_gain_high_power_vals_2g[] = { + 0x0a1aa652, 0x050739ce, 0x00000000, 0x00004002, 0x00007008, + 0x0000c010, 0x00010012, 0x00013014, 0x0001820a, 0x0001b211, + 0x0001e213, 0x00022411, 0x00025413, 0x00029811, 0x0002c813, + 0x00030a14, 0x00035a50, 0x00039c4c, 0x0003de8a, 0x00042e92, + 0x00046ed2, 0x0004bed5, 0x0004ff54, 0x00055fd5, 0x00f70081, + 0x00198eff, 0x00198eff, 0x00172000, 0x00172000, 0xf258a480, + 0xf258a480 +}; + +static const struct athn_gain ar9280_2_0_tx_gain_high_power = { + nitems(ar9280_2_0_tx_gain_regs), + ar9280_2_0_tx_gain_regs, + ar9280_2_0_tx_gain_high_power_vals_5g, + ar9280_2_0_tx_gain_high_power_vals_2g +}; + +/* + * AR9280 2.0 Rx gains. + */ +static const uint16_t ar9280_2_0_rx_gain_regs[] = { + P(0x09a00), P(0x09a04), P(0x09a08), P(0x09a0c), P(0x09a10), + P(0x09a14), P(0x09a18), P(0x09a1c), P(0x09a20), P(0x09a24), + P(0x09a28), P(0x09a2c), P(0x09a30), P(0x09a34), P(0x09a38), + P(0x09a3c), P(0x09a40), P(0x09a44), P(0x09a48), P(0x09a4c), + P(0x09a50), P(0x09a54), P(0x09a58), P(0x09a5c), P(0x09a60), + P(0x09a64), P(0x09a68), P(0x09a6c), P(0x09a70), P(0x09a74), + P(0x09a78), P(0x09a7c), P(0x09a80), P(0x09a84), P(0x09a88), + P(0x09a8c), P(0x09a90), P(0x09a94), P(0x09a98), P(0x09a9c), + P(0x09aa0), P(0x09aa4), P(0x09aa8), P(0x09aac), P(0x09ab0), + P(0x09ab4), P(0x09ab8), P(0x09abc), P(0x09ac0), P(0x09ac4), + P(0x09ac8), P(0x09acc), P(0x09ad0), P(0x09ad4), P(0x09ad8), + P(0x09adc), P(0x09ae0), P(0x09ae4), P(0x09ae8), P(0x09aec), + P(0x09af0), P(0x09af4), P(0x09af8), P(0x09afc), P(0x09b00), + P(0x09b04), P(0x09b08), P(0x09b0c), P(0x09b10), P(0x09b14), + P(0x09b18), P(0x09b1c), P(0x09b20), P(0x09b24), P(0x09b28), + P(0x09b2c), P(0x09b30), P(0x09b34), P(0x09b38), P(0x09b3c), + P(0x09b40), P(0x09b44), P(0x09b48), P(0x09b4c), P(0x09b50), + P(0x09b54), P(0x09b58), P(0x09b5c), P(0x09b60), P(0x09b64), + P(0x09b68), P(0x09b6c), P(0x09b70), P(0x09b74), P(0x09b78), + P(0x09b7c), P(0x09b80), P(0x09b84), P(0x09b88), P(0x09b8c), + P(0x09b90), P(0x09b94), P(0x09b98), P(0x09b9c), P(0x09ba0), + P(0x09ba4), P(0x09ba8), P(0x09bac), P(0x09bb0), P(0x09bb4), + P(0x09bb8), P(0x09bbc), P(0x09bc0), P(0x09bc4), P(0x09bc8), + P(0x09bcc), P(0x09bd0), P(0x09bd4), P(0x09bd8), P(0x09bdc), + P(0x09be0), P(0x09be4), P(0x09be8), P(0x09bec), P(0x09bf0), + P(0x09bf4), P(0x09bf8), P(0x09bfc), P(0x09848), P(0x0a848) +}; + +static const uint32_t ar9280_2_0_rx_gain_vals_5g[] = { + 0x00008184, 0x00008188, 0x0000818c, 0x00008190, 0x00008194, + 0x00008200, 0x00008204, 0x00008208, 0x0000820c, 0x00008210, + 0x00008214, 0x00008280, 0x00008284, 0x00008288, 0x0000828c, + 0x00008290, 0x00008300, 0x00008304, 0x00008308, 0x0000830c, + 0x00008310, 0x00008314, 0x00008380, 0x00008384, 0x00008388, + 0x0000838c, 0x00008390, 0x00008394, 0x0000a380, 0x0000a384, + 0x0000a388, 0x0000a38c, 0x0000a390, 0x0000a394, 0x0000a780, + 0x0000a784, 0x0000a788, 0x0000a78c, 0x0000a790, 0x0000a794, + 0x0000ab84, 0x0000ab88, 0x0000ab8c, 0x0000ab90, 0x0000ab94, + 0x0000af80, 0x0000af84, 0x0000af88, 0x0000af8c, 0x0000af90, + 0x0000af94, 0x0000b380, 0x0000b384, 0x0000b388, 0x0000b38c, + 0x0000b390, 0x0000b394, 0x0000b398, 0x0000b780, 0x0000b784, + 0x0000b788, 0x0000b78c, 0x0000b790, 0x0000b794, 0x0000b798, + 0x0000d784, 0x0000d788, 0x0000d78c, 0x0000d790, 0x0000f780, + 0x0000f784, 0x0000f788, 0x0000f78c, 0x0000f790, 0x0000f794, + 0x0000f7a4, 0x0000f7a8, 0x0000f7ac, 0x0000f7b0, 0x0000f7b4, + 0x0000f7a1, 0x0000f7a5, 0x0000f7a9, 0x0000f7ad, 0x0000f7b1, + 0x0000f7b5, 0x0000f7c5, 0x0000f7c9, 0x0000f7cd, 0x0000f7d1, + 0x0000f7d5, 0x0000f7c2, 0x0000f7c6, 0x0000f7ca, 0x0000f7ce, + 0x0000f7d2, 0x0000f7d6, 0x0000f7c3, 0x0000f7c7, 0x0000f7cb, + 0x0000f7d3, 0x0000f7d7, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x00001066, 0x00001066 +}; + +static const uint32_t ar9280_2_0_rx_gain_vals_2g[] = { + 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, + 0x00008000, 0x00008004, 0x00008008, 0x0000800c, 0x00008080, + 0x00008084, 0x00008088, 0x0000808c, 0x00008100, 0x00008104, + 0x00008108, 0x0000810c, 0x00008110, 0x00008114, 0x00008180, + 0x00008184, 0x00008188, 0x0000818c, 0x00008190, 0x00008194, + 0x000081a0, 0x0000820c, 0x000081a8, 0x00008284, 0x00008288, + 0x00008224, 0x00008290, 0x00008300, 0x00008304, 0x00008308, + 0x0000830c, 0x00008380, 0x00008384, 0x00008700, 0x00008704, + 0x00008708, 0x0000870c, 0x00008780, 0x00008784, 0x00008b00, + 0x00008b04, 0x00008b08, 0x00008b0c, 0x00008b80, 0x00008b84, + 0x00008b88, 0x00008b8c, 0x00008b90, 0x00008f80, 0x00008f84, + 0x00008f88, 0x00008f8c, 0x00008f90, 0x0000930c, 0x00009310, + 0x00009384, 0x00009388, 0x00009324, 0x00009704, 0x000096a4, + 0x000096a8, 0x00009710, 0x00009714, 0x00009720, 0x00009724, + 0x00009728, 0x0000972c, 0x000097a0, 0x000097a4, 0x000097a8, + 0x000097b0, 0x000097b4, 0x000097b8, 0x000097a5, 0x000097a9, + 0x000097ad, 0x000097b1, 0x000097b5, 0x000097b9, 0x000097c5, + 0x000097c9, 0x000097d1, 0x000097d5, 0x000097d9, 0x000097c6, + 0x000097ca, 0x000097ce, 0x000097d2, 0x000097d6, 0x000097c3, + 0x000097c7, 0x000097cb, 0x000097cf, 0x000097d7, 0x000097db, + 0x000097db, 0x000097db, 0x000097db, 0x000097db, 0x000097db, + 0x000097db, 0x000097db, 0x000097db, 0x000097db, 0x000097db, + 0x000097db, 0x000097db, 0x000097db, 0x000097db, 0x000097db, + 0x000097db, 0x000097db, 0x000097db, 0x000097db, 0x000097db, + 0x000097db, 0x000097db, 0x000097db, 0x000097db, 0x000097db, + 0x000097db, 0x000097db, 0x000097db, 0x00001063, 0x00001063 +}; + +static const struct athn_gain ar9280_2_0_rx_gain = { + nitems(ar9280_2_0_rx_gain_regs), + ar9280_2_0_rx_gain_regs, + ar9280_2_0_rx_gain_vals_5g, + ar9280_2_0_rx_gain_vals_2g +}; + +static const uint32_t ar9280_2_0_rx_gain_13db_backoff_vals_5g[] = { + 0x00008184, 0x00008188, 0x0000818c, 0x00008190, 0x00008194, + 0x00008200, 0x00008204, 0x00008208, 0x0000820c, 0x00008210, + 0x00008214, 0x00008280, 0x00008284, 0x00008288, 0x0000828c, + 0x00008290, 0x00008300, 0x00008304, 0x00008308, 0x0000830c, + 0x00008310, 0x00008314, 0x00008380, 0x00008384, 0x00008388, + 0x0000838c, 0x00008390, 0x00008394, 0x0000a380, 0x0000a384, + 0x0000a388, 0x0000a38c, 0x0000a390, 0x0000a394, 0x0000a780, + 0x0000a784, 0x0000a788, 0x0000a78c, 0x0000a790, 0x0000a794, + 0x0000ab84, 0x0000ab88, 0x0000ab8c, 0x0000ab90, 0x0000ab94, + 0x0000af80, 0x0000af84, 0x0000af88, 0x0000af8c, 0x0000af90, + 0x0000af94, 0x0000b380, 0x0000b384, 0x0000b388, 0x0000b38c, + 0x0000b390, 0x0000b394, 0x0000b398, 0x0000b780, 0x0000b784, + 0x0000b788, 0x0000b78c, 0x0000b790, 0x0000b794, 0x0000b798, + 0x0000d784, 0x0000d788, 0x0000d78c, 0x0000d790, 0x0000f780, + 0x0000f784, 0x0000f788, 0x0000f78c, 0x0000f790, 0x0000f794, + 0x0000f7a4, 0x0000f7a8, 0x0000f7ac, 0x0000f7b0, 0x0000f7b4, + 0x0000f7a1, 0x0000f7a5, 0x0000f7a9, 0x0000f7ad, 0x0000f7b1, + 0x0000f7b5, 0x0000f7c5, 0x0000f7c9, 0x0000f7cd, 0x0000f7d1, + 0x0000f7d5, 0x0000f7c2, 0x0000f7c6, 0x0000f7ca, 0x0000f7ce, + 0x0000f7d2, 0x0000f7d6, 0x0000f7c3, 0x0000f7c7, 0x0000f7cb, + 0x0000f7d3, 0x0000f7d7, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x00001066, 0x00001066 +}; + +static const uint32_t ar9280_2_0_rx_gain_13db_backoff_vals_2g[] = { + 0x00000290, 0x00000300, 0x00000304, 0x00000308, 0x0000030c, + 0x00008000, 0x00008004, 0x00008008, 0x0000800c, 0x00008080, + 0x00008084, 0x00008088, 0x0000808c, 0x00008100, 0x00008104, + 0x00008108, 0x0000810c, 0x00008110, 0x00008114, 0x00008180, + 0x00008184, 0x00008188, 0x0000818c, 0x00008190, 0x00008194, + 0x000081a0, 0x0000820c, 0x000081a8, 0x00008284, 0x00008288, + 0x00008224, 0x00008290, 0x00008300, 0x00008304, 0x00008308, + 0x0000830c, 0x00008380, 0x00008384, 0x00008700, 0x00008704, + 0x00008708, 0x0000870c, 0x00008780, 0x00008784, 0x00008b00, + 0x00008b04, 0x00008b08, 0x00008b0c, 0x00008b80, 0x00008b84, + 0x00008b88, 0x00008b8c, 0x00008b90, 0x00008f80, 0x00008f84, + 0x00008f88, 0x00008f8c, 0x00008f90, 0x00009310, 0x00009314, + 0x00009320, 0x00009324, 0x00009328, 0x0000932c, 0x00009330, + 0x00009334, 0x00009321, 0x00009325, 0x00009329, 0x0000932d, + 0x00009331, 0x00009335, 0x00009322, 0x00009326, 0x0000932a, + 0x0000932e, 0x00009332, 0x00009336, 0x00009323, 0x00009327, + 0x0000932b, 0x0000932f, 0x00009333, 0x00009337, 0x00009343, + 0x00009347, 0x0000934b, 0x0000934f, 0x00009353, 0x00009357, + 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, + 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, + 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, + 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, + 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, + 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, + 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, + 0x0000935b, 0x0000935b, 0x0000935b, 0x0000105a, 0x0000105a +}; + +static const struct athn_gain ar9280_2_0_rx_gain_13db_backoff = { + nitems(ar9280_2_0_rx_gain_regs), + ar9280_2_0_rx_gain_regs, + ar9280_2_0_rx_gain_13db_backoff_vals_5g, + ar9280_2_0_rx_gain_13db_backoff_vals_2g +}; + +static const uint32_t ar9280_2_0_rx_gain_23db_backoff_vals_5g[] = { + 0x00008184, 0x00008188, 0x0000818c, 0x00008190, 0x00008194, + 0x00008200, 0x00008204, 0x00008208, 0x0000820c, 0x00008210, + 0x00008214, 0x00008280, 0x00008284, 0x00008288, 0x0000828c, + 0x00008290, 0x00008300, 0x00008304, 0x00008308, 0x0000830c, + 0x00008310, 0x00008314, 0x00008380, 0x00008384, 0x00008388, + 0x0000838c, 0x00008390, 0x00008394, 0x0000a380, 0x0000a384, + 0x0000a388, 0x0000a38c, 0x0000a390, 0x0000a394, 0x0000a780, + 0x0000a784, 0x0000a788, 0x0000a78c, 0x0000a790, 0x0000a794, + 0x0000ab84, 0x0000ab88, 0x0000ab8c, 0x0000ab90, 0x0000ab94, + 0x0000af80, 0x0000af84, 0x0000af88, 0x0000af8c, 0x0000af90, + 0x0000af94, 0x0000b380, 0x0000b384, 0x0000b388, 0x0000b38c, + 0x0000b390, 0x0000b394, 0x0000b398, 0x0000b780, 0x0000b784, + 0x0000b788, 0x0000b78c, 0x0000b790, 0x0000b794, 0x0000b798, + 0x0000d784, 0x0000d788, 0x0000d78c, 0x0000d790, 0x0000f780, + 0x0000f784, 0x0000f788, 0x0000f78c, 0x0000f790, 0x0000f794, + 0x0000f7a4, 0x0000f7a8, 0x0000f7ac, 0x0000f7b0, 0x0000f7b4, + 0x0000f7a1, 0x0000f7a5, 0x0000f7a9, 0x0000f7ad, 0x0000f7b1, + 0x0000f7b5, 0x0000f7c5, 0x0000f7c9, 0x0000f7cd, 0x0000f7d1, + 0x0000f7d5, 0x0000f7c2, 0x0000f7c6, 0x0000f7ca, 0x0000f7ce, + 0x0000f7d2, 0x0000f7d6, 0x0000f7c3, 0x0000f7c7, 0x0000f7cb, + 0x0000f7d3, 0x0000f7d7, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, + 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x00001066, 0x00001066 +}; + +static const uint32_t ar9280_2_0_rx_gain_23db_backoff_vals_2g[] = { + 0x00000290, 0x00000300, 0x00000304, 0x00000308, 0x0000030c, + 0x00008000, 0x00008004, 0x00008008, 0x0000800c, 0x00008080, + 0x00008084, 0x00008088, 0x0000808c, 0x00008100, 0x00008104, + 0x00008108, 0x0000810c, 0x00008110, 0x00008114, 0x00008180, + 0x00008184, 0x00008188, 0x0000818c, 0x00008190, 0x00008194, + 0x000081a0, 0x0000820c, 0x000081a8, 0x00008284, 0x00008288, + 0x00008224, 0x00008290, 0x00008300, 0x00008304, 0x00008308, + 0x0000830c, 0x00008380, 0x00008384, 0x00008700, 0x00008704, + 0x00008708, 0x0000870c, 0x00008780, 0x00008784, 0x00008b00, + 0x00008b04, 0x00008b08, 0x00008b0c, 0x00008b10, 0x00008b80, + 0x00008b84, 0x00008b88, 0x00008b8c, 0x00008b90, 0x00008b94, + 0x00008b98, 0x00008ba4, 0x00008ba8, 0x00008bac, 0x00008bb0, + 0x00008bb4, 0x00008ba1, 0x00008ba5, 0x00008ba9, 0x00008bad, + 0x00008bb1, 0x00008bb5, 0x00008ba2, 0x00008ba6, 0x00008baa, + 0x00008bae, 0x00008bb2, 0x00008bb6, 0x00008ba3, 0x00008ba7, + 0x00008bab, 0x00008baf, 0x00008bb3, 0x00008bb7, 0x00008bc3, + 0x00008bc7, 0x00008bcb, 0x00008bcf, 0x00008bd3, 0x00008bd7, + 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, + 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, + 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, + 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, + 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, + 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, + 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, + 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, + 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00001055, 0x00001055 +}; + +static const struct athn_gain ar9280_2_0_rx_gain_23db_backoff = { + nitems(ar9280_2_0_rx_gain_regs), + ar9280_2_0_rx_gain_regs, + ar9280_2_0_rx_gain_23db_backoff_vals_5g, + ar9280_2_0_rx_gain_23db_backoff_vals_2g +}; + +/* + * Serializer/Deserializer programming. + */ + +static const uint32_t ar9280_2_0_serdes_regs[] = { + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES, + AR_PCIE_SERDES2, +}; + +static const uint32_t ar9280_2_0_serdes_vals[] = { + 0x9248fd00, + 0x24924924, + 0xa8000019, + 0x13160820, + 0xe5980560, +#ifdef ATHN_PCIE_CLKREQ + 0xc01dcffc, +#else + 0xc01dcffd, +#endif + 0x1aaabe41, + 0xbe105554, + 0x00043007, + 0x00000000 +}; + +static const struct athn_serdes ar9280_2_0_serdes = { + nitems(ar9280_2_0_serdes_vals), + ar9280_2_0_serdes_regs, + ar9280_2_0_serdes_vals +}; diff --git a/sys/dev/athn/headers/ar9285.h b/sys/dev/athn/headers/ar9285.h new file mode 100644 --- /dev/null +++ b/sys/dev/athn/headers/ar9285.h @@ -0,0 +1,24 @@ +#ifndef AR9285 +#define AR9285 + +int ar9285_attach(struct athn_softc *); +void ar9285_setup(struct athn_softc *); +void ar9285_swap_rom(struct athn_softc *); +const struct ar_spur_chan *ar9285_get_spur_chans(struct athn_softc *, int); +void ar9285_init_from_rom(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +void ar9285_pa_calib(struct athn_softc *); +void ar9271_pa_calib(struct athn_softc *); +int ar9285_cl_cal(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +void ar9271_load_ani(struct athn_softc *); +int ar9285_init_calib(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +void ar9285_get_pdadcs(struct athn_softc *, struct ieee80211_channel *, + int, uint8_t, uint8_t *, uint8_t *); +void ar9285_set_power_calib(struct athn_softc *, + struct ieee80211_channel *); +void ar9285_set_txpower(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); + +#endif /* AR9285 */ \ No newline at end of file diff --git a/sys/dev/athn/headers/ar9285reg.h b/sys/dev/athn/headers/ar9285reg.h new file mode 100644 --- /dev/null +++ b/sys/dev/athn/headers/ar9285reg.h @@ -0,0 +1,977 @@ +/* $OpenBSD: ar9285reg.h,v 1.9 2019/02/01 16:15:07 stsp Exp $ */ + +/*- + * Copyright (c) 2009 Damien Bergamini + * Copyright (c) 2008-2009 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define AR9285_MAX_CHAINS 1 + +#define AR9285_PHY_CCA_MIN_GOOD_VAL_2GHZ (-127) +#define AR9285_PHY_CCA_MAX_GOOD_VAL_2GHZ (-108) +#define AR9271_PHY_CCA_MIN_GOOD_VAL_2GHZ (-127) +#define AR9271_PHY_CCA_MAX_GOOD_VAL_2GHZ (-116) + +#define AR9285_CL_CAL_REDO_THRESH 1 + +/* + * Analog registers. + */ +#define AR9285_AN_RF2G1 0x7820 +#define AR9285_AN_RF2G2 0x7824 +#define AR9285_AN_RF2G3 0x7828 +#define AR9285_AN_RF2G4 0x782c +#define AR9285_AN_RF2G5 0x7830 +#define AR9285_AN_RF2G6 0x7834 +#define AR9285_AN_RF2G7 0x7838 +#define AR9285_AN_RF2G8 0x783c +#define AR9285_AN_RF2G9 0x7840 +#define AR9285_AN_RXTXBB1 0x7854 +#define AR9285_AN_TOP2 0x7868 +#define AR9285_AN_TOP3 0x786c +#define AR9285_AN_TOP4 0x7870 + +/* Bits for AR9285_AN_RF2G1. */ +#define AR9285_AN_RF2G1_ENPACAL 0x00000800 +#define AR9285_AN_RF2G1_PDPAOUT 0x00800000 +#define AR9285_AN_RF2G1_PDPADRV2 0x01000000 +#define AR9285_AN_RF2G1_PDPADRV1 0x02000000 + +/* Bits for AR9285_AN_RF2G2. */ +#define AR9285_AN_RF2G2_OFFCAL 0x00001000 + +/* Bits for AR9285_AN_RF2G3. */ +#define AR9285_AN_RF2G3_DB1_2_M 0x00000007 +#define AR9285_AN_RF2G3_DB1_2_S 0 +#define AR9285_AN_RF2G3_DB1_1_M 0x00000038 +#define AR9285_AN_RF2G3_DB1_1_S 3 +#define AR9285_AN_RF2G3_DB1_0_M 0x000001c0 +#define AR9285_AN_RF2G3_DB1_0_S 6 +#define AR9285_AN_RF2G3_OB_4_M 0x00000e00 +#define AR9285_AN_RF2G3_OB_4_S 9 +#define AR9285_AN_RF2G3_OB_3_M 0x00007000 +#define AR9285_AN_RF2G3_OB_3_S 12 +#define AR9285_AN_RF2G3_OB_2_M 0x00038000 +#define AR9285_AN_RF2G3_OB_2_S 15 +#define AR9285_AN_RF2G3_OB_1_M 0x001c0000 +#define AR9285_AN_RF2G3_OB_1_S 18 +#define AR9285_AN_RF2G3_OB_0_M 0x00e00000 +#define AR9285_AN_RF2G3_OB_0_S 21 +#define AR9285_AN_RF2G3_PDVCCOMP 0x02000000 +#define AR9271_AN_RF2G3_CCOMP_M 0x00000fff +#define AR9271_AN_RF2G3_CCOMP_S 0 +#define AR9271_AN_RF2G3_OB_QAM_M 0x00007000 +#define AR9271_AN_RF2G3_OB_QAM_S 12 +#define AR9271_AN_RF2G3_OB_PSK_M 0x00038000 +#define AR9271_AN_RF2G3_OB_PSK_S 15 +#define AR9271_AN_RF2G3_OB_CCK_M 0x001c0000 +#define AR9271_AN_RF2G3_OB_CCK_S 18 +#define AR9271_AN_RF2G3_DB1_M 0x00e00000 +#define AR9271_AN_RF2G3_DB1_S 21 + +/* Bits for AR9285_AN_RF2G4. */ +#define AR9285_AN_RF2G4_DB2_4_M 0x00003800 +#define AR9285_AN_RF2G4_DB2_4_S 11 +#define AR9285_AN_RF2G4_DB2_3_M 0x0001c000 +#define AR9285_AN_RF2G4_DB2_3_S 14 +#define AR9285_AN_RF2G4_DB2_2_M 0x000e0000 +#define AR9285_AN_RF2G4_DB2_2_S 17 +#define AR9285_AN_RF2G4_DB2_1_M 0x00700000 +#define AR9285_AN_RF2G4_DB2_1_S 20 +#define AR9285_AN_RF2G4_DB2_0_M 0x03800000 +#define AR9285_AN_RF2G4_DB2_0_S 23 +#define AR9285_AN_RF2G4_DB1_4_M 0x1c000000 +#define AR9285_AN_RF2G4_DB1_4_S 26 +#define AR9285_AN_RF2G4_DB1_3_M 0xe0000000 +#define AR9285_AN_RF2G4_DB1_3_S 29 +#define AR9271_AN_RF2G4_DB2_M 0xe0000000 +#define AR9271_AN_RF2G4_DB2_S 29 + +/* Bits for AR9285_AN_RF2G5. */ +#define AR9285_AN_RF2G5_IC50TX_M 0x00000700 +#define AR9285_AN_RF2G5_IC50TX_S 8 + +/* Bits for AR9285_AN_RF2G6. */ +#define AR9285_AN_RF2G6_CCOMP_M 0x00007800 +#define AR9285_AN_RF2G6_CCOMP_S 11 +#define AR9285_AN_RF2G6_OFFS_6_1 0x03f00000 +#define AR9285_AN_RF2G6_OFFS(i) (1 << (19 + (i))) +#define AR9271_AN_RF2G6_OFFS_6_0 0x07f00000 +#define AR9271_AN_RF2G6_OFFS(i) (1 << (20 + (i))) + +/* Bits for AR9285_AN_RF2G7. */ +#define AR9285_AN_RF2G7_PWDDB 0x00000002 +#define AR9285_AN_RF2G7_PADRVGN2TAB0_M 0xe0000000 +#define AR9285_AN_RF2G7_PADRVGN2TAB0_S 29 + +/* Bits for AR9285_AN_RF2G8. */ +#define AR9285_AN_RF2G8_PADRVGN2TAB0_M 0x0001c000 +#define AR9285_AN_RF2G8_PADRVGN2TAB0_S 14 + +/* Bits for AR9285_AN_RXTXBB1. */ +#define AR9285_AN_RXTXBB1_SPARE9 0x00000001 +#define AR9285_AN_RXTXBB1_PDRXTXBB1 0x00000020 +#define AR9285_AN_RXTXBB1_PDV2I 0x00000080 +#define AR9285_AN_RXTXBB1_PDDACIF 0x00000100 + +/* Bits for AR9285_AN_TOP2. */ +#define AR9285_AN_TOP2_DEFAULT 0xca0358a0 /* XXX magic */ + +/* Bits for AR9285_AN_TOP3. */ +#define AR9285_AN_TOP3_XPABIAS_LVL_M 0x0000000c +#define AR9285_AN_TOP3_XPABIAS_LVL_S 2 +#define AR9285_AN_TOP3_PWDDAC 0x00800000 + +/* Bits for AR9285_AN_TOP4. */ +#define AR9285_AN_TOP4_DEFAULT 0x10142c00 /* XXX magic */ +#define AR9285_AN_TOP4_UNLOCKED 0x10142c14 /* XXX magic */ + +/* Bits for AR_PHY_MULTICHAIN_GAIN_CTL. */ +#define AR9285_PHY_ANT_DIV_CTL_ALL_M 0x7f000000 +#define AR9285_PHY_ANT_DIV_CTL_ALL_S 24 +#define AR9285_PHY_ANT_DIV_CTL_M 0x01000000 +#define AR9285_PHY_ANT_DIV_CTL_S 24 +#define AR9285_PHY_ANT_DIV_ALT_LNACONF_M 0x06000000 +#define AR9285_PHY_ANT_DIV_ALT_LNACONF_S 25 +#define AR9285_PHY_ANT_DIV_MAIN_LNACONF_M 0x18000000 +#define AR9285_PHY_ANT_DIV_MAIN_LNACONF_S 27 +#define AR9285_PHY_ANT_DIV_ALT_GAINTB_M 0x20000000 +#define AR9285_PHY_ANT_DIV_ALT_GAINTB_S 29 +#define AR9285_PHY_ANT_DIV_MAIN_GAINTB_M 0x40000000 +#define AR9285_PHY_ANT_DIV_MAIN_GAINTB_S 30 + + +/* Macro to "pack" registers to 16-bit to save some .rodata space. */ +#define P(x) (x) + +/* + * AR9285 1.2 initialization values. + */ +static const uint16_t ar9285_1_2_regs[] = { + P(0x01030), P(0x01070), P(0x010b0), P(0x010f0), P(0x08014), + P(0x0801c), P(0x08318), P(0x09804), P(0x09820), P(0x09824), + P(0x09828), P(0x09834), P(0x09838), P(0x09840), P(0x09844), + P(0x09848), P(0x0a848), P(0x09850), P(0x09858), P(0x0985c), + P(0x09860), P(0x09864), P(0x09868), P(0x0986c), P(0x09914), + P(0x09918), P(0x09924), P(0x09944), P(0x09960), P(0x09964), + P(0x099b8), P(0x099bc), P(0x099c0), P(0x099c4), P(0x099c8), + P(0x099cc), P(0x099d0), P(0x099d4), P(0x099d8), P(0x09a00), + P(0x09a04), P(0x09a08), P(0x09a0c), P(0x09a10), P(0x09a14), + P(0x09a18), P(0x09a1c), P(0x09a20), P(0x09a24), P(0x09a28), + P(0x09a2c), P(0x09a30), P(0x09a34), P(0x09a38), P(0x09a3c), + P(0x09a40), P(0x09a44), P(0x09a48), P(0x09a4c), P(0x09a50), + P(0x09a54), P(0x09a58), P(0x09a5c), P(0x09a60), P(0x09a64), + P(0x09a68), P(0x09a6c), P(0x09a70), P(0x09a74), P(0x09a78), + P(0x09a7c), P(0x09a80), P(0x09a84), P(0x09a88), P(0x09a8c), + P(0x09a90), P(0x09a94), P(0x09a98), P(0x09a9c), P(0x09aa0), + P(0x09aa4), P(0x09aa8), P(0x09aac), P(0x09ab0), P(0x09ab4), + P(0x09ab8), P(0x09abc), P(0x09ac0), P(0x09ac4), P(0x09ac8), + P(0x09acc), P(0x09ad0), P(0x09ad4), P(0x09ad8), P(0x09adc), + P(0x09ae0), P(0x09ae4), P(0x09ae8), P(0x09aec), P(0x09af0), + P(0x09af4), P(0x09af8), P(0x09afc), P(0x09b00), P(0x09b04), + P(0x09b08), P(0x09b0c), P(0x09b10), P(0x09b14), P(0x09b18), + P(0x09b1c), P(0x09b20), P(0x09b24), P(0x09b28), P(0x09b2c), + P(0x09b30), P(0x09b34), P(0x09b38), P(0x09b3c), P(0x09b40), + P(0x09b44), P(0x09b48), P(0x09b4c), P(0x09b50), P(0x09b54), + P(0x09b58), P(0x09b5c), P(0x09b60), P(0x09b64), P(0x09b68), + P(0x09b6c), P(0x09b70), P(0x09b74), P(0x09b78), P(0x09b7c), + P(0x09b80), P(0x09b84), P(0x09b88), P(0x09b8c), P(0x09b90), + P(0x09b94), P(0x09b98), P(0x09b9c), P(0x09ba0), P(0x09ba4), + P(0x09ba8), P(0x09bac), P(0x09bb0), P(0x09bb4), P(0x09bb8), + P(0x09bbc), P(0x09bc0), P(0x09bc4), P(0x09bc8), P(0x09bcc), + P(0x09bd0), P(0x09bd4), P(0x09bd8), P(0x09bdc), P(0x09be0), + P(0x09be4), P(0x09be8), P(0x09bec), P(0x09bf0), P(0x09bf4), + P(0x09bf8), P(0x09bfc), P(0x0aa00), P(0x0aa04), P(0x0aa08), + P(0x0aa0c), P(0x0aa10), P(0x0aa14), P(0x0aa18), P(0x0aa1c), + P(0x0aa20), P(0x0aa24), P(0x0aa28), P(0x0aa2c), P(0x0aa30), + P(0x0aa34), P(0x0aa38), P(0x0aa3c), P(0x0aa40), P(0x0aa44), + P(0x0aa48), P(0x0aa4c), P(0x0aa50), P(0x0aa54), P(0x0aa58), + P(0x0aa5c), P(0x0aa60), P(0x0aa64), P(0x0aa68), P(0x0aa6c), + P(0x0aa70), P(0x0aa74), P(0x0aa78), P(0x0aa7c), P(0x0aa80), + P(0x0aa84), P(0x0aa88), P(0x0aa8c), P(0x0aa90), P(0x0aa94), + P(0x0aa98), P(0x0aa9c), P(0x0aaa0), P(0x0aaa4), P(0x0aaa8), + P(0x0aaac), P(0x0aab0), P(0x0aab4), P(0x0aab8), P(0x0aabc), + P(0x0aac0), P(0x0aac4), P(0x0aac8), P(0x0aacc), P(0x0aad0), + P(0x0aad4), P(0x0aad8), P(0x0aadc), P(0x0aae0), P(0x0aae4), + P(0x0aae8), P(0x0aaec), P(0x0aaf0), P(0x0aaf4), P(0x0aaf8), + P(0x0aafc), P(0x0ab00), P(0x0ab04), P(0x0ab08), P(0x0ab0c), + P(0x0ab10), P(0x0ab14), P(0x0ab18), P(0x0ab1c), P(0x0ab20), + P(0x0ab24), P(0x0ab28), P(0x0ab2c), P(0x0ab30), P(0x0ab34), + P(0x0ab38), P(0x0ab3c), P(0x0ab40), P(0x0ab44), P(0x0ab48), + P(0x0ab4c), P(0x0ab50), P(0x0ab54), P(0x0ab58), P(0x0ab5c), + P(0x0ab60), P(0x0ab64), P(0x0ab68), P(0x0ab6c), P(0x0ab70), + P(0x0ab74), P(0x0ab78), P(0x0ab7c), P(0x0ab80), P(0x0ab84), + P(0x0ab88), P(0x0ab8c), P(0x0ab90), P(0x0ab94), P(0x0ab98), + P(0x0ab9c), P(0x0aba0), P(0x0aba4), P(0x0aba8), P(0x0abac), + P(0x0abb0), P(0x0abb4), P(0x0abb8), P(0x0abbc), P(0x0abc0), + P(0x0abc4), P(0x0abc8), P(0x0abcc), P(0x0abd0), P(0x0abd4), + P(0x0abd8), P(0x0abdc), P(0x0abe0), P(0x0abe4), P(0x0abe8), + P(0x0abec), P(0x0abf0), P(0x0abf4), P(0x0abf8), P(0x0abfc), + P(0x0a204), P(0x0a20c), P(0x0b20c), P(0x0a21c), P(0x0a230), + P(0x0a250), P(0x0a358) +}; + +static const uint32_t ar9285_1_2_vals_2g40[] = { + 0x000002c0, 0x00000318, 0x00007c70, 0x00000000, 0x10801600, + 0x12e00057, 0x00006880, 0x000003c4, 0x02020200, 0x01000e0e, + 0x0a020001, 0x00000e0e, 0x00000007, 0x206a012e, 0x03721620, + 0x00001053, 0x00001053, 0x6d4000e2, 0x7ec84d2e, 0x3137605e, + 0x00058d20, 0x0001ce00, 0x5ac640d0, 0x06903881, 0x00001130, + 0x00000016, 0xd00a800d, 0xffbc1020, 0x00000000, 0x00000000, + 0x0000421c, 0x00000c00, 0x05eea6d4, 0x06336f77, 0x6af6532f, + 0x08f186c8, 0x00046384, 0x00000000, 0x00000000, 0x00058084, + 0x00058088, 0x0005808c, 0x00058100, 0x00058104, 0x00058108, + 0x0005810c, 0x00058110, 0x00058114, 0x00058180, 0x00058184, + 0x00058188, 0x0005818c, 0x00058190, 0x00058194, 0x000581a0, + 0x0005820c, 0x000581a8, 0x00058284, 0x00058288, 0x00058224, + 0x00058290, 0x00058300, 0x00058304, 0x00058308, 0x0005830c, + 0x00058380, 0x00058384, 0x00068700, 0x00068704, 0x00068708, + 0x0006870c, 0x00068780, 0x00068784, 0x00078b00, 0x00078b04, + 0x00078b08, 0x00078b0c, 0x00078b80, 0x00078b84, 0x00078b88, + 0x00078b8c, 0x00078b90, 0x000caf80, 0x000caf84, 0x000caf88, + 0x000caf8c, 0x000caf90, 0x000db30c, 0x000db310, 0x000db384, + 0x000db388, 0x000db324, 0x000eb704, 0x000eb6a4, 0x000eb6a8, + 0x000eb710, 0x000eb714, 0x000eb720, 0x000eb724, 0x000eb728, + 0x000eb72c, 0x000eb7a0, 0x000eb7a4, 0x000eb7a8, 0x000eb7b0, + 0x000eb7b4, 0x000eb7b8, 0x000eb7a5, 0x000eb7a9, 0x000eb7ad, + 0x000eb7b1, 0x000eb7b5, 0x000eb7b9, 0x000eb7c5, 0x000eb7c9, + 0x000eb7d1, 0x000eb7d5, 0x000eb7d9, 0x000eb7c6, 0x000eb7ca, + 0x000eb7ce, 0x000eb7d2, 0x000eb7d6, 0x000eb7c3, 0x000eb7c7, + 0x000eb7cb, 0x000eb7cf, 0x000eb7d7, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x00058084, 0x00058088, 0x0005808c, + 0x00058100, 0x00058104, 0x00058108, 0x0005810c, 0x00058110, + 0x00058114, 0x00058180, 0x00058184, 0x00058188, 0x0005818c, + 0x00058190, 0x00058194, 0x000581a0, 0x0005820c, 0x000581a8, + 0x00058284, 0x00058288, 0x00058224, 0x00058290, 0x00058300, + 0x00058304, 0x00058308, 0x0005830c, 0x00058380, 0x00058384, + 0x00068700, 0x00068704, 0x00068708, 0x0006870c, 0x00068780, + 0x00068784, 0x00078b00, 0x00078b04, 0x00078b08, 0x00078b0c, + 0x00078b80, 0x00078b84, 0x00078b88, 0x00078b8c, 0x00078b90, + 0x000caf80, 0x000caf84, 0x000caf88, 0x000caf8c, 0x000caf90, + 0x000db30c, 0x000db310, 0x000db384, 0x000db388, 0x000db324, + 0x000eb704, 0x000eb6a4, 0x000eb6a8, 0x000eb710, 0x000eb714, + 0x000eb720, 0x000eb724, 0x000eb728, 0x000eb72c, 0x000eb7a0, + 0x000eb7a4, 0x000eb7a8, 0x000eb7b0, 0x000eb7b4, 0x000eb7b8, + 0x000eb7a5, 0x000eb7a9, 0x000eb7ad, 0x000eb7b1, 0x000eb7b5, + 0x000eb7b9, 0x000eb7c5, 0x000eb7c9, 0x000eb7d1, 0x000eb7d5, + 0x000eb7d9, 0x000eb7c6, 0x000eb7ca, 0x000eb7ce, 0x000eb7d2, + 0x000eb7d6, 0x000eb7c3, 0x000eb7c7, 0x000eb7cb, 0x000eb7cf, + 0x000eb7d7, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x00000004, 0x0001f000, 0x0001f000, 0x1883800a, 0x00000210, + 0x0004a000, 0x7999aa0e +}; + +static const uint32_t ar9285_1_2_vals_2g20[] = { + 0x00000160, 0x0000018c, 0x00003e38, 0x00000000, 0x08400b00, + 0x12e0002b, 0x00003440, 0x00000300, 0x02020200, 0x01000e0e, + 0x0a020001, 0x00000e0e, 0x00000007, 0x206a012e, 0x03721620, + 0x00001053, 0x00001053, 0x6d4000e2, 0x7ec84d2e, 0x3137605e, + 0x00058d20, 0x0001ce00, 0x5ac640d0, 0x06903881, 0x00000898, + 0x0000000b, 0xd00a800d, 0xffbc1020, 0x00000000, 0x00000000, + 0x0000421c, 0x00000c00, 0x05eea6d4, 0x06336f77, 0x6af6532f, + 0x08f186c8, 0x00046384, 0x00000000, 0x00000000, 0x00058084, + 0x00058088, 0x0005808c, 0x00058100, 0x00058104, 0x00058108, + 0x0005810c, 0x00058110, 0x00058114, 0x00058180, 0x00058184, + 0x00058188, 0x0005818c, 0x00058190, 0x00058194, 0x000581a0, + 0x0005820c, 0x000581a8, 0x00058284, 0x00058288, 0x00058224, + 0x00058290, 0x00058300, 0x00058304, 0x00058308, 0x0005830c, + 0x00058380, 0x00058384, 0x00068700, 0x00068704, 0x00068708, + 0x0006870c, 0x00068780, 0x00068784, 0x00078b00, 0x00078b04, + 0x00078b08, 0x00078b0c, 0x00078b80, 0x00078b84, 0x00078b88, + 0x00078b8c, 0x00078b90, 0x000caf80, 0x000caf84, 0x000caf88, + 0x000caf8c, 0x000caf90, 0x000db30c, 0x000db310, 0x000db384, + 0x000db388, 0x000db324, 0x000eb704, 0x000eb6a4, 0x000eb6a8, + 0x000eb710, 0x000eb714, 0x000eb720, 0x000eb724, 0x000eb728, + 0x000eb72c, 0x000eb7a0, 0x000eb7a4, 0x000eb7a8, 0x000eb7b0, + 0x000eb7b4, 0x000eb7b8, 0x000eb7a5, 0x000eb7a9, 0x000eb7ad, + 0x000eb7b1, 0x000eb7b5, 0x000eb7b9, 0x000eb7c5, 0x000eb7c9, + 0x000eb7d1, 0x000eb7d5, 0x000eb7d9, 0x000eb7c6, 0x000eb7ca, + 0x000eb7ce, 0x000eb7d2, 0x000eb7d6, 0x000eb7c3, 0x000eb7c7, + 0x000eb7cb, 0x000eb7cf, 0x000eb7d7, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x00058084, 0x00058088, 0x0005808c, + 0x00058100, 0x00058104, 0x00058108, 0x0005810c, 0x00058110, + 0x00058114, 0x00058180, 0x00058184, 0x00058188, 0x0005818c, + 0x00058190, 0x00058194, 0x000581a0, 0x0005820c, 0x000581a8, + 0x00058284, 0x00058288, 0x00058224, 0x00058290, 0x00058300, + 0x00058304, 0x00058308, 0x0005830c, 0x00058380, 0x00058384, + 0x00068700, 0x00068704, 0x00068708, 0x0006870c, 0x00068780, + 0x00068784, 0x00078b00, 0x00078b04, 0x00078b08, 0x00078b0c, + 0x00078b80, 0x00078b84, 0x00078b88, 0x00078b8c, 0x00078b90, + 0x000caf80, 0x000caf84, 0x000caf88, 0x000caf8c, 0x000caf90, + 0x000db30c, 0x000db310, 0x000db384, 0x000db388, 0x000db324, + 0x000eb704, 0x000eb6a4, 0x000eb6a8, 0x000eb710, 0x000eb714, + 0x000eb720, 0x000eb724, 0x000eb728, 0x000eb72c, 0x000eb7a0, + 0x000eb7a4, 0x000eb7a8, 0x000eb7b0, 0x000eb7b4, 0x000eb7b8, + 0x000eb7a5, 0x000eb7a9, 0x000eb7ad, 0x000eb7b1, 0x000eb7b5, + 0x000eb7b9, 0x000eb7c5, 0x000eb7c9, 0x000eb7d1, 0x000eb7d5, + 0x000eb7d9, 0x000eb7c6, 0x000eb7ca, 0x000eb7ce, 0x000eb7d2, + 0x000eb7d6, 0x000eb7c3, 0x000eb7c7, 0x000eb7cb, 0x000eb7cf, + 0x000eb7d7, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x00000004, 0x0001f000, 0x0001f000, 0x1883800a, 0x00000108, + 0x0004a000, 0x7999aa0e +}; + +static const uint16_t ar9285_1_2_cm_regs[] = { + P(0x0000c), P(0x00030), P(0x00034), P(0x00040), P(0x00044), + P(0x00048), P(0x0004c), P(0x00050), P(0x00054), P(0x00800), + P(0x00804), P(0x00808), P(0x0080c), P(0x00810), P(0x00814), + P(0x00818), P(0x0081c), P(0x00820), P(0x00824), P(0x01040), + P(0x01044), P(0x01048), P(0x0104c), P(0x01050), P(0x01054), + P(0x01058), P(0x0105c), P(0x01060), P(0x01064), P(0x01230), + P(0x01270), P(0x01038), P(0x01078), P(0x010b8), P(0x010f8), + P(0x01138), P(0x01178), P(0x011b8), P(0x011f8), P(0x01238), + P(0x01278), P(0x012b8), P(0x012f8), P(0x01338), P(0x01378), + P(0x013b8), P(0x013f8), P(0x01438), P(0x01478), P(0x014b8), + P(0x014f8), P(0x01538), P(0x01578), P(0x015b8), P(0x015f8), + P(0x01638), P(0x01678), P(0x016b8), P(0x016f8), P(0x01738), + P(0x01778), P(0x017b8), P(0x017f8), P(0x0103c), P(0x0107c), + P(0x010bc), P(0x010fc), P(0x0113c), P(0x0117c), P(0x011bc), + P(0x011fc), P(0x0123c), P(0x0127c), P(0x012bc), P(0x012fc), + P(0x0133c), P(0x0137c), P(0x013bc), P(0x013fc), P(0x0143c), + P(0x0147c), P(0x04030), P(0x0403c), P(0x04024), P(0x04060), + P(0x04064), P(0x07010), P(0x07034), P(0x07038), P(0x08004), + P(0x08008), P(0x0800c), P(0x08018), P(0x08020), P(0x08038), + P(0x0803c), P(0x08048), P(0x08054), P(0x08058), P(0x0805c), + P(0x08060), P(0x08064), P(0x08070), P(0x080c0), P(0x080c4), + P(0x080c8), P(0x080cc), P(0x080d0), P(0x080d4), P(0x080d8), + P(0x080e0), P(0x080e4), P(0x080e8), P(0x080ec), P(0x080f0), + P(0x080f4), P(0x080f8), P(0x080fc), P(0x08100), P(0x08104), + P(0x08108), P(0x0810c), P(0x08110), P(0x08118), P(0x0811c), + P(0x08120), P(0x08124), P(0x08128), P(0x0812c), P(0x08130), + P(0x08134), P(0x08138), P(0x0813c), P(0x08144), P(0x08168), + P(0x0816c), P(0x08170), P(0x08174), P(0x08178), P(0x0817c), + P(0x081c0), P(0x081d0), P(0x081ec), P(0x081f0), P(0x081f4), + P(0x081f8), P(0x081fc), P(0x08200), P(0x08204), P(0x08208), + P(0x0820c), P(0x08210), P(0x08214), P(0x08218), P(0x0821c), + P(0x08220), P(0x08224), P(0x08228), P(0x0822c), P(0x08230), + P(0x08234), P(0x08238), P(0x0823c), P(0x08240), P(0x08244), + P(0x08248), P(0x0824c), P(0x08250), P(0x08254), P(0x08258), + P(0x0825c), P(0x08260), P(0x08264), P(0x08270), P(0x08274), + P(0x08278), P(0x0827c), P(0x08284), P(0x08288), P(0x0828c), + P(0x08294), P(0x08298), P(0x0829c), P(0x08300), P(0x08314), + P(0x08328), P(0x0832c), P(0x08330), P(0x08334), P(0x08338), + P(0x0833c), P(0x08340), P(0x08344), P(0x09808), P(0x0980c), + P(0x09810), P(0x09814), P(0x0981c), P(0x0982c), P(0x09830), + P(0x0983c), P(0x0984c), P(0x09854), P(0x09900), P(0x09904), + P(0x09908), P(0x0990c), P(0x09910), P(0x0991c), P(0x09920), + P(0x09928), P(0x0992c), P(0x09934), P(0x09938), P(0x0993c), + P(0x09940), P(0x09948), P(0x0994c), P(0x09954), P(0x09958), + P(0x09968), P(0x09970), P(0x09974), P(0x09978), P(0x0997c), + P(0x09980), P(0x09984), P(0x09988), P(0x0998c), P(0x09990), + P(0x09994), P(0x09998), P(0x0999c), P(0x099a0), P(0x099a4), + P(0x099a8), P(0x099ac), P(0x099b0), P(0x099b4), P(0x099dc), + P(0x099e0), P(0x099e4), P(0x099e8), P(0x099ec), P(0x099f0), + P(0x0a208), P(0x0a210), P(0x0a214), P(0x0a218), P(0x0a220), + P(0x0a224), P(0x0a228), P(0x0a22c), P(0x0a234), P(0x0a238), + P(0x0a244), P(0x0a248), P(0x0a24c), P(0x0a254), P(0x0a258), + P(0x0a25c), P(0x0a260), P(0x0a268), P(0x0a26c), P(0x0d270), + P(0x0d35c), P(0x0d360), P(0x0d364), P(0x0d368), P(0x0d36c), + P(0x0d370), P(0x0d374), P(0x0d378), P(0x0d37c), P(0x0d380), + P(0x0d384), P(0x0a388), P(0x0a38c), P(0x0a390), P(0x0a39c), + P(0x0a3a0), P(0x0a3a4), P(0x0a3a8), P(0x0a3ac), P(0x0a3b0), + P(0x0a3b4), P(0x0a3b8), P(0x0a3bc), P(0x0a3c0), P(0x0a3c4), + P(0x0a3cc), P(0x0a3d0), P(0x0a3d4), P(0x0a3e4), P(0x0a3e8), + P(0x0a3ec), P(0x07800), P(0x07804), P(0x07808), P(0x0780c), + P(0x07810), P(0x0781c), P(0x07824), P(0x0782c), P(0x07834), + P(0x07844), P(0x07848), P(0x0784c), P(0x07850), P(0x07854), + P(0x07858), P(0x0785c), P(0x07860), P(0x07864), P(0x07868), + P(0x07870) +}; + +static const uint32_t ar9285_1_2_cm_vals[] = { + 0x00000000, 0x00020045, 0x00000005, 0x00000000, 0x00000008, + 0x00000008, 0x00000010, 0x00000000, 0x0000001f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x002ffc0f, + 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, + 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x00000002, 0x0000001f, 0x00000000, + 0x00000000, 0x00000031, 0x00000002, 0x000004c2, 0x00000000, + 0x00000000, 0x00000000, 0x00000700, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000fc78f, + 0x0000000f, 0x00000000, 0x00000000, 0x2a80001a, 0x05dc01e0, + 0x1f402710, 0x01f40000, 0x00001e00, 0x00000000, 0x00400000, + 0xffffffff, 0x0000ffff, 0x003f3f3f, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00020000, 0x00020000, 0x00000001, + 0x00000052, 0x00000000, 0x00000168, 0x000100aa, 0x00003210, + 0x08f04810, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, + 0x00000000, 0x32143320, 0xfaa4fa50, 0x00000100, 0x00000000, + 0x00000000, 0x0000320a, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00100000, 0x0010f400, + 0x00000100, 0x0001e800, 0x00000000, 0x00000000, 0x00000000, + 0x400000ff, 0x00080922, 0x88a00010, 0x00000000, 0x40000000, + 0x003e4180, 0x00000000, 0x0000002c, 0x0000002c, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0x00000000, + 0x00000000, 0x00000001, 0x00000302, 0x00000e00, 0x00ff0000, + 0x00000000, 0x00010380, 0x00481043, 0x00000000, 0xafe68e30, + 0xfd14e000, 0x9c0a9f6b, 0x00000000, 0x0000a000, 0x00000000, + 0x00200400, 0x0040233c, 0x00000044, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x01002310, 0x10000fff, 0x04900000, + 0x00000001, 0x00000004, 0x1e1f2022, 0x0a0b0c0d, 0x00000000, + 0x14750604, 0x9280c00a, 0x00020028, 0x5f3ca3de, 0x2108ecff, + 0x000003ce, 0x192bb514, 0x00000000, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x201fff00, 0x2def0400, 0x03051000, 0x00000820, 0x00000000, + 0x00000000, 0xaaaaaaaa, 0x3c466478, 0x0cc80caa, 0x00000000, + 0x803e68c8, 0x4080a333, 0x00206c10, 0x009c4060, 0x01834061, + 0x00000400, 0x000003b5, 0x00000000, 0x20202020, 0x20202020, + 0x00000000, 0xfffffffc, 0x00000000, 0x00000000, 0x0ccb5380, + 0x15151501, 0xdfa90f01, 0x00000000, 0x0ebae9e6, 0x0d820820, + 0x07ffffef, 0x0fffffe7, 0x17ffffe5, 0x1fffffe4, 0x37ffffe3, + 0x3fffffe3, 0x57ffffe3, 0x5fffffe2, 0x7fffffe2, 0x7f3c7bba, + 0xf3307ff0, 0x0c000000, 0x20202020, 0x20202020, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x20202020, 0x20202020, 0x20202020, 0x00000000, 0x18c43433, + 0x00f70081, 0x00140000, 0x0e4548d8, 0x54214514, 0x02025830, + 0x71c0d388, 0x00000000, 0x00d86fff, 0x6e36d97b, 0x71400087, + 0x000c0db6, 0x6db6246f, 0x6d9b66db, 0x6d8c6dba, 0x00040000, + 0xdb003012, 0x04924914, 0x21084210, 0xf7d7ffde, 0xc2034080, + 0x10142c00 +}; + +static const struct athn_ini ar9285_1_2_ini = { + nitems(ar9285_1_2_regs), + ar9285_1_2_regs, + NULL, /* 2GHz only. */ + NULL, /* 2GHz only. */ + ar9285_1_2_vals_2g40, + ar9285_1_2_vals_2g20, + nitems(ar9285_1_2_cm_regs), + ar9285_1_2_cm_regs, + ar9285_1_2_cm_vals +}; + +/* + * AR9271 programming. + */ +static const uint16_t ar9271_regs[] = { + P(0x01030), P(0x01070), P(0x010b0), P(0x010f0), P(0x08014), + P(0x0801c), P(0x08318), P(0x09804), P(0x09820), P(0x09824), + P(0x09828), P(0x09834), P(0x09838), P(0x09840), P(0x09844), + P(0x09848), P(0x0a848), P(0x09850), P(0x09858), P(0x0985c), + P(0x09860), P(0x09864), P(0x09868), P(0x0986c), P(0x09910), + P(0x09914), P(0x09918), P(0x09924), P(0x09944), P(0x09960), + P(0x09964), P(0x099b8), P(0x099bc), P(0x099c0), P(0x099c4), + P(0x099c8), P(0x099cc), P(0x099d0), P(0x099d4), P(0x099d8), + P(0x09a00), P(0x09a04), P(0x09a08), P(0x09a0c), P(0x09a10), + P(0x09a14), P(0x09a18), P(0x09a1c), P(0x09a20), P(0x09a24), + P(0x09a28), P(0x09a2c), P(0x09a30), P(0x09a34), P(0x09a38), + P(0x09a3c), P(0x09a40), P(0x09a44), P(0x09a48), P(0x09a4c), + P(0x09a50), P(0x09a54), P(0x09a58), P(0x09a5c), P(0x09a60), + P(0x09a64), P(0x09a68), P(0x09a6c), P(0x09a70), P(0x09a74), + P(0x09a78), P(0x09a7c), P(0x09a80), P(0x09a84), P(0x09a88), + P(0x09a8c), P(0x09a90), P(0x09a94), P(0x09a98), P(0x09a9c), + P(0x09aa0), P(0x09aa4), P(0x09aa8), P(0x09aac), P(0x09ab0), + P(0x09ab4), P(0x09ab8), P(0x09abc), P(0x09ac0), P(0x09ac4), + P(0x09ac8), P(0x09acc), P(0x09ad0), P(0x09ad4), P(0x09ad8), + P(0x09adc), P(0x09ae0), P(0x09ae4), P(0x09ae8), P(0x09aec), + P(0x09af0), P(0x09af4), P(0x09af8), P(0x09afc), P(0x09b00), + P(0x09b04), P(0x09b08), P(0x09b0c), P(0x09b10), P(0x09b14), + P(0x09b18), P(0x09b1c), P(0x09b20), P(0x09b24), P(0x09b28), + P(0x09b2c), P(0x09b30), P(0x09b34), P(0x09b38), P(0x09b3c), + P(0x09b40), P(0x09b44), P(0x09b48), P(0x09b4c), P(0x09b50), + P(0x09b54), P(0x09b58), P(0x09b5c), P(0x09b60), P(0x09b64), + P(0x09b68), P(0x09b6c), P(0x09b70), P(0x09b74), P(0x09b78), + P(0x09b7c), P(0x09b80), P(0x09b84), P(0x09b88), P(0x09b8c), + P(0x09b90), P(0x09b94), P(0x09b98), P(0x09b9c), P(0x09ba0), + P(0x09ba4), P(0x09ba8), P(0x09bac), P(0x09bb0), P(0x09bb4), + P(0x09bb8), P(0x09bbc), P(0x09bc0), P(0x09bc4), P(0x09bc8), + P(0x09bcc), P(0x09bd0), P(0x09bd4), P(0x09bd8), P(0x09bdc), + P(0x09be0), P(0x09be4), P(0x09be8), P(0x09bec), P(0x09bf0), + P(0x09bf4), P(0x09bf8), P(0x09bfc), P(0x0aa00), P(0x0aa04), + P(0x0aa08), P(0x0aa0c), P(0x0aa10), P(0x0aa14), P(0x0aa18), + P(0x0aa1c), P(0x0aa20), P(0x0aa24), P(0x0aa28), P(0x0aa2c), + P(0x0aa30), P(0x0aa34), P(0x0aa38), P(0x0aa3c), P(0x0aa40), + P(0x0aa44), P(0x0aa48), P(0x0aa4c), P(0x0aa50), P(0x0aa54), + P(0x0aa58), P(0x0aa5c), P(0x0aa60), P(0x0aa64), P(0x0aa68), + P(0x0aa6c), P(0x0aa70), P(0x0aa74), P(0x0aa78), P(0x0aa7c), + P(0x0aa80), P(0x0aa84), P(0x0aa88), P(0x0aa8c), P(0x0aa90), + P(0x0aa94), P(0x0aa98), P(0x0aa9c), P(0x0aaa0), P(0x0aaa4), + P(0x0aaa8), P(0x0aaac), P(0x0aab0), P(0x0aab4), P(0x0aab8), + P(0x0aabc), P(0x0aac0), P(0x0aac4), P(0x0aac8), P(0x0aacc), + P(0x0aad0), P(0x0aad4), P(0x0aad8), P(0x0aadc), P(0x0aae0), + P(0x0aae4), P(0x0aae8), P(0x0aaec), P(0x0aaf0), P(0x0aaf4), + P(0x0aaf8), P(0x0aafc), P(0x0ab00), P(0x0ab04), P(0x0ab08), + P(0x0ab0c), P(0x0ab10), P(0x0ab14), P(0x0ab18), P(0x0ab1c), + P(0x0ab20), P(0x0ab24), P(0x0ab28), P(0x0ab2c), P(0x0ab30), + P(0x0ab34), P(0x0ab38), P(0x0ab3c), P(0x0ab40), P(0x0ab44), + P(0x0ab48), P(0x0ab4c), P(0x0ab50), P(0x0ab54), P(0x0ab58), + P(0x0ab5c), P(0x0ab60), P(0x0ab64), P(0x0ab68), P(0x0ab6c), + P(0x0ab70), P(0x0ab74), P(0x0ab78), P(0x0ab7c), P(0x0ab80), + P(0x0ab84), P(0x0ab88), P(0x0ab8c), P(0x0ab90), P(0x0ab94), + P(0x0ab98), P(0x0ab9c), P(0x0aba0), P(0x0aba4), P(0x0aba8), + P(0x0abac), P(0x0abb0), P(0x0abb4), P(0x0abb8), P(0x0abbc), + P(0x0abc0), P(0x0abc4), P(0x0abc8), P(0x0abcc), P(0x0abd0), + P(0x0abd4), P(0x0abd8), P(0x0abdc), P(0x0abe0), P(0x0abe4), + P(0x0abe8), P(0x0abec), P(0x0abf0), P(0x0abf4), P(0x0abf8), + P(0x0abfc), P(0x0a204), P(0x0a20c), P(0x0b20c), P(0x0a21c), + P(0x0a230), P(0x0a250), P(0x0a358) +}; + +static const uint32_t ar9271_vals_2g40[] = { + 0x000002c0, 0x00000318, 0x00007c70, 0x00000000, 0x10801600, + 0x12e00057, 0x00006880, 0x000003c4, 0x02020200, 0x01000e0e, + 0x3a020001, 0x00000e0e, 0x00000007, 0x206a012e, 0x03721620, + 0x00001053, 0x00001053, 0x6d4000e2, 0x7ec84d2e, 0x3137605e, + 0x00058d18, 0x0001ce00, 0x5ac640d0, 0x06903881, 0x30002310, + 0x00001130, 0x00000016, 0xd00a800d, 0xffbc1020, 0x00000000, + 0x00000000, 0x0000421c, 0x00000c00, 0x05eea6d4, 0x06336f77, + 0x6af6532f, 0x08f186c8, 0x00046384, 0x00000000, 0x00000000, + 0x00058084, 0x00058088, 0x0005808c, 0x00058100, 0x00058104, + 0x00058108, 0x0005810c, 0x00058110, 0x00058114, 0x00058180, + 0x00058184, 0x00058188, 0x0005818c, 0x00058190, 0x00058194, + 0x000581a0, 0x0005820c, 0x000581a8, 0x00058284, 0x00058288, + 0x00058224, 0x00058290, 0x00058300, 0x00058304, 0x00058308, + 0x0005830c, 0x00058380, 0x00058384, 0x00068700, 0x00068704, + 0x00068708, 0x0006870c, 0x00068780, 0x00068784, 0x00078b00, + 0x00078b04, 0x00078b08, 0x00078b0c, 0x00078b80, 0x00078b84, + 0x00078b88, 0x00078b8c, 0x00078b90, 0x000caf80, 0x000caf84, + 0x000caf88, 0x000caf8c, 0x000caf90, 0x000db30c, 0x000db310, + 0x000db384, 0x000db388, 0x000db324, 0x000eb704, 0x000eb6a4, + 0x000eb6a8, 0x000eb710, 0x000eb714, 0x000eb720, 0x000eb724, + 0x000eb728, 0x000eb72c, 0x000eb7a0, 0x000eb7a4, 0x000eb7a8, + 0x000eb7b0, 0x000eb7b4, 0x000eb7b8, 0x000eb7a5, 0x000eb7a9, + 0x000eb7ad, 0x000eb7b1, 0x000eb7b5, 0x000eb7b9, 0x000eb7c5, + 0x000eb7c9, 0x000eb7d1, 0x000eb7d5, 0x000eb7d9, 0x000eb7c6, + 0x000eb7ca, 0x000eb7ce, 0x000eb7d2, 0x000eb7d6, 0x000eb7c3, + 0x000eb7c7, 0x000eb7cb, 0x000eb7cf, 0x000eb7d7, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x00058084, 0x00058088, + 0x0005808c, 0x00058100, 0x00058104, 0x00058108, 0x0005810c, + 0x00058110, 0x00058114, 0x00058180, 0x00058184, 0x00058188, + 0x0005818c, 0x00058190, 0x00058194, 0x000581a0, 0x0005820c, + 0x000581a8, 0x00058284, 0x00058288, 0x00058224, 0x00058290, + 0x00058300, 0x00058304, 0x00058308, 0x0005830c, 0x00058380, + 0x00058384, 0x00068700, 0x00068704, 0x00068708, 0x0006870c, + 0x00068780, 0x00068784, 0x00078b00, 0x00078b04, 0x00078b08, + 0x00078b0c, 0x00078b80, 0x00078b84, 0x00078b88, 0x00078b8c, + 0x00078b90, 0x000caf80, 0x000caf84, 0x000caf88, 0x000caf8c, + 0x000caf90, 0x000db30c, 0x000db310, 0x000db384, 0x000db388, + 0x000db324, 0x000eb704, 0x000eb6a4, 0x000eb6a8, 0x000eb710, + 0x000eb714, 0x000eb720, 0x000eb724, 0x000eb728, 0x000eb72c, + 0x000eb7a0, 0x000eb7a4, 0x000eb7a8, 0x000eb7b0, 0x000eb7b4, + 0x000eb7b8, 0x000eb7a5, 0x000eb7a9, 0x000eb7ad, 0x000eb7b1, + 0x000eb7b5, 0x000eb7b9, 0x000eb7c5, 0x000eb7c9, 0x000eb7d1, + 0x000eb7d5, 0x000eb7d9, 0x000eb7c6, 0x000eb7ca, 0x000eb7ce, + 0x000eb7d2, 0x000eb7d6, 0x000eb7c3, 0x000eb7c7, 0x000eb7cb, + 0x000eb7cf, 0x000eb7d7, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x00000004, 0x0001f000, 0x0001f000, 0x1883800a, + 0x00000210, 0x0004a000, 0x7999aa0e +}; + +static const uint32_t ar9271_vals_2g20[] = { + 0x00000160, 0x0000018c, 0x00003e38, 0x00000000, 0x08400b00, + 0x12e0002b, 0x00003440, 0x00000300, 0x02020200, 0x01000e0e, + 0x3a020001, 0x00000e0e, 0x00000007, 0x206a012e, 0x03721620, + 0x00001053, 0x00001053, 0x6d4000e2, 0x7ec84d2e, 0x3137605e, + 0x00058d18, 0x0001ce00, 0x5ac640d0, 0x06903881, 0x30002310, + 0x00000898, 0x0000000b, 0xd00a800d, 0xffbc1020, 0x00000000, + 0x00000000, 0x0000421c, 0x00000c00, 0x05eea6d4, 0x06336f77, + 0x6af6532f, 0x08f186c8, 0x00046384, 0x00000000, 0x00000000, + 0x00058084, 0x00058088, 0x0005808c, 0x00058100, 0x00058104, + 0x00058108, 0x0005810c, 0x00058110, 0x00058114, 0x00058180, + 0x00058184, 0x00058188, 0x0005818c, 0x00058190, 0x00058194, + 0x000581a0, 0x0005820c, 0x000581a8, 0x00058284, 0x00058288, + 0x00058224, 0x00058290, 0x00058300, 0x00058304, 0x00058308, + 0x0005830c, 0x00058380, 0x00058384, 0x00068700, 0x00068704, + 0x00068708, 0x0006870c, 0x00068780, 0x00068784, 0x00078b00, + 0x00078b04, 0x00078b08, 0x00078b0c, 0x00078b80, 0x00078b84, + 0x00078b88, 0x00078b8c, 0x00078b90, 0x000caf80, 0x000caf84, + 0x000caf88, 0x000caf8c, 0x000caf90, 0x000db30c, 0x000db310, + 0x000db384, 0x000db388, 0x000db324, 0x000eb704, 0x000eb6a4, + 0x000eb6a8, 0x000eb710, 0x000eb714, 0x000eb720, 0x000eb724, + 0x000eb728, 0x000eb72c, 0x000eb7a0, 0x000eb7a4, 0x000eb7a8, + 0x000eb7b0, 0x000eb7b4, 0x000eb7b8, 0x000eb7a5, 0x000eb7a9, + 0x000eb7ad, 0x000eb7b1, 0x000eb7b5, 0x000eb7b9, 0x000eb7c5, + 0x000eb7c9, 0x000eb7d1, 0x000eb7d5, 0x000eb7d9, 0x000eb7c6, + 0x000eb7ca, 0x000eb7ce, 0x000eb7d2, 0x000eb7d6, 0x000eb7c3, + 0x000eb7c7, 0x000eb7cb, 0x000eb7cf, 0x000eb7d7, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x00058084, 0x00058088, + 0x0005808c, 0x00058100, 0x00058104, 0x00058108, 0x0005810c, + 0x00058110, 0x00058114, 0x00058180, 0x00058184, 0x00058188, + 0x0005818c, 0x00058190, 0x00058194, 0x000581a0, 0x0005820c, + 0x000581a8, 0x00058284, 0x00058288, 0x00058224, 0x00058290, + 0x00058300, 0x00058304, 0x00058308, 0x0005830c, 0x00058380, + 0x00058384, 0x00068700, 0x00068704, 0x00068708, 0x0006870c, + 0x00068780, 0x00068784, 0x00078b00, 0x00078b04, 0x00078b08, + 0x00078b0c, 0x00078b80, 0x00078b84, 0x00078b88, 0x00078b8c, + 0x00078b90, 0x000caf80, 0x000caf84, 0x000caf88, 0x000caf8c, + 0x000caf90, 0x000db30c, 0x000db310, 0x000db384, 0x000db388, + 0x000db324, 0x000eb704, 0x000eb6a4, 0x000eb6a8, 0x000eb710, + 0x000eb714, 0x000eb720, 0x000eb724, 0x000eb728, 0x000eb72c, + 0x000eb7a0, 0x000eb7a4, 0x000eb7a8, 0x000eb7b0, 0x000eb7b4, + 0x000eb7b8, 0x000eb7a5, 0x000eb7a9, 0x000eb7ad, 0x000eb7b1, + 0x000eb7b5, 0x000eb7b9, 0x000eb7c5, 0x000eb7c9, 0x000eb7d1, + 0x000eb7d5, 0x000eb7d9, 0x000eb7c6, 0x000eb7ca, 0x000eb7ce, + 0x000eb7d2, 0x000eb7d6, 0x000eb7c3, 0x000eb7c7, 0x000eb7cb, + 0x000eb7cf, 0x000eb7d7, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, + 0x000eb7db, 0x00000004, 0x0001f000, 0x0001f000, 0x1883800a, + 0x00000108, 0x0004a000, 0x7999aa0e +}; + +static const uint16_t ar9271_cm_regs[] = { + P(0x0000c), P(0x00030), P(0x00034), P(0x00040), P(0x00044), + P(0x00048), P(0x0004c), P(0x00050), P(0x00054), P(0x00800), + P(0x00804), P(0x00808), P(0x0080c), P(0x00810), P(0x00814), + P(0x00818), P(0x0081c), P(0x00820), P(0x00824), P(0x01040), + P(0x01044), P(0x01048), P(0x0104c), P(0x01050), P(0x01054), + P(0x01058), P(0x0105c), P(0x01060), P(0x01064), P(0x01230), + P(0x01270), P(0x01038), P(0x01078), P(0x010b8), P(0x010f8), + P(0x01138), P(0x01178), P(0x011b8), P(0x011f8), P(0x01238), + P(0x01278), P(0x012b8), P(0x012f8), P(0x01338), P(0x01378), + P(0x013b8), P(0x013f8), P(0x01438), P(0x01478), P(0x014b8), + P(0x014f8), P(0x01538), P(0x01578), P(0x015b8), P(0x015f8), + P(0x01638), P(0x01678), P(0x016b8), P(0x016f8), P(0x01738), + P(0x01778), P(0x017b8), P(0x017f8), P(0x0103c), P(0x0107c), + P(0x010bc), P(0x010fc), P(0x0113c), P(0x0117c), P(0x011bc), + P(0x011fc), P(0x0123c), P(0x0127c), P(0x012bc), P(0x012fc), + P(0x0133c), P(0x0137c), P(0x013bc), P(0x013fc), P(0x0143c), + P(0x0147c), P(0x04030), P(0x0403c), P(0x04024), P(0x04060), + P(0x04064), P(0x08004), P(0x08008), P(0x0800c), P(0x08018), + P(0x08020), P(0x08038), P(0x0803c), P(0x08048), P(0x08054), + P(0x08058), P(0x0805c), P(0x08060), P(0x08064), P(0x08070), + P(0x080b0), P(0x080b4), P(0x080b8), P(0x080bc), P(0x080c0), + P(0x080c4), P(0x080c8), P(0x080cc), P(0x080d0), P(0x080d4), + P(0x080d8), P(0x080e0), P(0x080e4), P(0x080e8), P(0x080ec), + P(0x080f0), P(0x080f4), P(0x080f8), P(0x080fc), P(0x08100), + P(0x08104), P(0x08108), P(0x0810c), P(0x08110), P(0x08118), + P(0x0811c), P(0x08120), P(0x08124), P(0x08128), P(0x0812c), + P(0x08130), P(0x08134), P(0x08138), P(0x0813c), P(0x08144), + P(0x08168), P(0x0816c), P(0x08170), P(0x08174), P(0x08178), + P(0x0817c), P(0x081c0), P(0x081d0), P(0x081ec), P(0x081f0), + P(0x081f4), P(0x081f8), P(0x081fc), P(0x08200), P(0x08204), + P(0x08208), P(0x0820c), P(0x08210), P(0x08214), P(0x08218), + P(0x0821c), P(0x08220), P(0x08224), P(0x08228), P(0x0822c), + P(0x08230), P(0x08234), P(0x08238), P(0x0823c), P(0x08240), + P(0x08244), P(0x08248), P(0x0824c), P(0x08250), P(0x08254), + P(0x08258), P(0x0825c), P(0x08260), P(0x08264), P(0x08270), + P(0x08274), P(0x08278), P(0x0827c), P(0x08284), P(0x08288), + P(0x0828c), P(0x08294), P(0x08298), P(0x0829c), P(0x08300), + P(0x08314), P(0x08328), P(0x0832c), P(0x08330), P(0x08334), + P(0x08338), P(0x0833c), P(0x08340), P(0x08344), P(0x07010), + P(0x07034), P(0x07038), P(0x07800), P(0x07804), P(0x07808), + P(0x0780c), P(0x07810), P(0x07814), P(0x0781c), P(0x07828), + P(0x0782c), P(0x07830), P(0x07834), P(0x0783c), P(0x07840), + P(0x07844), P(0x07848), P(0x0784c), P(0x07850), P(0x07854), + P(0x07858), P(0x0785c), P(0x07860), P(0x07864), P(0x07868), + P(0x07870), P(0x09808), P(0x0980c), P(0x09810), P(0x09814), + P(0x0981c), P(0x0982c), P(0x09830), P(0x0983c), P(0x0984c), + P(0x09854), P(0x09900), P(0x09904), P(0x09908), P(0x0990c), + P(0x0991c), P(0x09920), P(0x09928), P(0x0992c), P(0x09934), + P(0x09938), P(0x0993c), P(0x09940), P(0x09948), P(0x0994c), + P(0x09954), P(0x09958), P(0x09968), P(0x09970), P(0x09974), + P(0x09978), P(0x0997c), P(0x09980), P(0x09984), P(0x09988), + P(0x0998c), P(0x09990), P(0x09994), P(0x09998), P(0x0999c), + P(0x099a0), P(0x099a4), P(0x099a8), P(0x099ac), P(0x099b0), + P(0x099b4), P(0x099dc), P(0x099e0), P(0x099e4), P(0x099e8), + P(0x099ec), P(0x099f0), P(0x0a208), P(0x0a210), P(0x0a214), + P(0x0a218), P(0x0a220), P(0x0a224), P(0x0a228), P(0x0a22c), + P(0x0a234), P(0x0a238), P(0x0a244), P(0x0a248), P(0x0a24c), + P(0x0a254), P(0x0a258), P(0x0a25c), P(0x0a260), P(0x0a268), + P(0x0a26c), P(0x0a388), P(0x0a38c), P(0x0a390), P(0x0a39c), + P(0x0a3a0), P(0x0a3a4), P(0x0a3a8), P(0x0a3ac), P(0x0a3b0), + P(0x0a3b4), P(0x0a3b8), P(0x0a3bc), P(0x0a3c0), P(0x0a3c4), + P(0x0a3cc), P(0x0a3d0), P(0x0a3d4), P(0x0a3e4), P(0x0a3e8), + P(0x0a3ec), P(0x0a3f0), P(0x0a3f4), P(0x0d270), P(0x0d35c), + P(0x0d360), P(0x0d364), P(0x0d368), P(0x0d36c), P(0x0d370), + P(0x0d374), P(0x0d378), P(0x0d37c), P(0x0d380), P(0x0d384) +}; + +static const uint32_t ar9271_cm_vals[] = { + 0x00000000, 0x00020045, 0x00000005, 0x00000000, 0x00000008, + 0x00000008, 0x00000010, 0x00000000, 0x0000001f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x002ffc0f, + 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, + 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000002, 0x00000002, 0x0000001f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000700, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x000fc78f, 0x0000000f, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2a80001a, + 0x05dc01e0, 0x1f402710, 0x01f40000, 0x00001e00, 0x00000000, + 0x00400000, 0xffffffff, 0x0000ffff, 0x003f3f3f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00020000, 0x00020000, + 0x00000001, 0x00000052, 0x00000000, 0x00000168, 0x000100aa, + 0x00003210, 0x08f04810, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, + 0x00000000, 0x00000000, 0x32143320, 0xfaa4fa50, 0x00000100, + 0x00000000, 0x00000000, 0x0000320a, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00100000, + 0x0010f400, 0x00000100, 0x0001e800, 0x00000000, 0x00000000, + 0x00000000, 0x400000ff, 0x00080922, 0x88a00010, 0x00000000, + 0x40000000, 0x003e4180, 0x00000000, 0x0000002c, 0x0000002c, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, + 0x00000000, 0x00000000, 0x00000001, 0x00000302, 0x00000e00, + 0x00ff0000, 0x00000000, 0x00010380, 0x00581043, 0x00000030, + 0x00000002, 0x000004c2, 0x00140000, 0x0e4548d8, 0x54214514, + 0x02025820, 0x71c0d388, 0x924934a8, 0x00000000, 0x66964300, + 0x8db6d961, 0x8db6d96c, 0x6140008b, 0x72ee0a72, 0xbbfffffc, + 0x000c0db6, 0x6db6246f, 0x6d9b66db, 0x6d8c6dba, 0x00040000, + 0xdb003012, 0x04924914, 0x21084210, 0xf7d7ffde, 0xc2034080, + 0x10142c00, 0x00000000, 0xafe68e30, 0xfd14e000, 0x9c0a9f6b, + 0x00000000, 0x0000a000, 0x00000000, 0x00200400, 0x0040233c, + 0x00000044, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x10000fff, 0x04900000, 0x00000001, 0x00000004, 0x1e1f2022, + 0x0a0b0c0d, 0x00000000, 0x14750604, 0x9280c00a, 0x00020028, + 0x5f3ca3de, 0x0108ecff, 0x000003ce, 0x192bb514, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x201fff00, 0x2def0400, 0x03051000, + 0x00000820, 0x00000000, 0x00000000, 0xaaaaaaaa, 0x3c466478, + 0x0cc80caa, 0x00000000, 0x803e68c8, 0x4080a333, 0x00206c10, + 0x009c4060, 0x01834061, 0x00000400, 0x000003b5, 0x00000000, + 0x20202020, 0x20202020, 0x00000000, 0xfffffffc, 0x00000000, + 0x00000000, 0x0ccb5380, 0x15151501, 0xdfa90f01, 0x00000000, + 0x0ebae9e6, 0x0c000000, 0x20202020, 0x20202020, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x20202020, 0x20202020, 0x20202020, 0x00000000, 0x18c43433, + 0x00f70081, 0x01036a2f, 0x00000000, 0x0d820820, 0x07ffffef, + 0x0fffffe7, 0x17ffffe5, 0x1fffffe4, 0x37ffffe3, 0x3fffffe3, + 0x57ffffe3, 0x5fffffe2, 0x7fffffe2, 0x7f3c7bba, 0xf3307ff0 +}; + +static const struct athn_ini ar9271_ini = { + nitems(ar9271_regs), + ar9271_regs, + NULL, /* 2GHz only. */ + NULL, /* 2GHz only. */ + ar9271_vals_2g40, + ar9271_vals_2g20, + nitems(ar9271_cm_regs), + ar9271_cm_regs, + ar9271_cm_vals +}; + +/* + * AR9285 1.2 Tx gains. + */ +static const uint16_t ar9285_1_2_tx_gain_regs[] = { + P(0x0a300), P(0x0a304), P(0x0a308), P(0x0a30c), P(0x0a310), + P(0x0a314), P(0x0a318), P(0x0a31c), P(0x0a320), P(0x0a324), + P(0x0a328), P(0x0a32c), P(0x0a330), P(0x0a334), P(0x0a338), + P(0x0a33c), P(0x0a340), P(0x0a344), P(0x0a348), P(0x0a34c), + P(0x0a350), P(0x0a354), P(0x07814), P(0x07828), P(0x07830), + P(0x07838), P(0x0783c), P(0x07840), P(0x0786c), P(0x07820), + P(0x0a274), P(0x0a278), P(0x0a27c), P(0x0a394), P(0x0a398), + P(0x0a3dc), P(0x0a3e0) +}; + +static const uint32_t ar9285_1_2_tx_gain_vals_2g[] = { + 0x00000000, 0x00009200, 0x00010208, 0x00019608, 0x00022618, + 0x0002a6c9, 0x00031710, 0x00035718, 0x00038758, 0x0003c75a, + 0x0004075c, 0x0004475e, 0x0004679f, 0x000487df, 0x0003891e, + 0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, + 0x0003e9df, 0x0003e9df, 0x924934a8, 0x26d2491b, 0xedb6d96e, + 0xfac68801, 0x0001fffe, 0xffeb1a20, 0x48609eb4, 0x00000c04, + 0x0a21a652, 0x39ce739c, 0x050e039c, 0x39ce739c, 0x0000039c, + 0x39ce739c, 0x0000039c +}; + +static const struct athn_gain ar9285_1_2_tx_gain = { + nitems(ar9285_1_2_tx_gain_regs), + ar9285_1_2_tx_gain_regs, + NULL, /* 2GHz only. */ + ar9285_1_2_tx_gain_vals_2g +}; + +static const uint32_t ar9285_1_2_tx_gain_high_power_vals_2g[] = { + 0x00000000, 0x00006200, 0x00008201, 0x0000b240, 0x0000d241, + 0x0000f600, 0x00012800, 0x00016802, 0x0001b805, 0x00021a80, + 0x00028b00, 0x0002ab40, 0x0002cd80, 0x00033d82, 0x0003891e, + 0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, + 0x0003e9df, 0x0003e9df, 0x924934a8, 0x26d2491b, 0xedb6d96e, + 0xfac68803, 0x0001fffe, 0xffeb1a20, 0x08609ebe, 0x00000c00, + 0x0a216652, 0x0e739ce7, 0x050380e7, 0x0e739ce7, 0x000000e7, + 0x0e739ce7, 0x000000e7 +}; + +static const struct athn_gain ar9285_1_2_tx_gain_high_power = { + nitems(ar9285_1_2_tx_gain_regs), + ar9285_1_2_tx_gain_regs, + NULL, /* 2GHz only. */ + ar9285_1_2_tx_gain_high_power_vals_2g +}; + +/* + * AR9285 XE 2.0 Tx gains. + */ +static const uint32_t ar9285_2_0_tx_gain_vals_2g[] = { + 0x00000000, 0x00009200, 0x00010208, 0x00019608, 0x00022618, + 0x0002a6c9, 0x00031710, 0x00035718, 0x00038758, 0x0003c75a, + 0x0004075c, 0x0004475e, 0x0004679f, 0x000487df, 0x0003891e, + 0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, + 0x0003e9df, 0x0003e9df, 0x92497ca8, 0x2ad2491b, 0xedb6da6e, + 0xdac71441, 0x2481f6fe, 0xba5f638c, 0x48609eb4, 0x00000c04, + 0x0a21a652, 0x39ce739c, 0x050e039c, 0x39ce739c, 0x0000039c, + 0x39ce739c, 0x0000039c +}; + +static const struct athn_gain ar9285_2_0_tx_gain = { + nitems(ar9285_1_2_tx_gain_regs), + ar9285_1_2_tx_gain_regs, + NULL, /* 2GHz only. */ + ar9285_2_0_tx_gain_vals_2g +}; + +static const uint32_t ar9285_2_0_tx_gain_high_power_vals_2g[] = { + 0x00000000, 0x00006200, 0x00008201, 0x0000b240, 0x0000d241, + 0x0000f600, 0x00012800, 0x00016802, 0x0001b805, 0x00021a80, + 0x00028b00, 0x0002ab40, 0x0002cd80, 0x00033d82, 0x0003891e, + 0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, + 0x0003e9df, 0x0003e9df, 0x92497ca8, 0x2ad2491b, 0xedb6da6e, + 0xdac71443, 0x2481f6fe, 0xba5f638c, 0x08609ebe, 0x00000c00, + 0x0a216652, 0x0e739ce7, 0x050380e7, 0x0e739ce7, 0x000000e7, + 0x0e739ce7, 0x000000e7 +}; + +static const struct athn_gain ar9285_2_0_tx_gain_high_power = { + nitems(ar9285_1_2_tx_gain_regs), + ar9285_1_2_tx_gain_regs, + NULL, /* 2GHz only. */ + ar9285_2_0_tx_gain_high_power_vals_2g +}; + +/* + * AR9271 Tx gains. + */ +static const uint16_t ar9271_tx_gain_regs[] = { + P(0x0a300), P(0x0a304), P(0x0a308), P(0x0a30c), P(0x0a310), + P(0x0a314), P(0x0a318), P(0x0a31c), P(0x0a320), P(0x0a324), + P(0x0a328), P(0x0a32c), P(0x0a330), P(0x0a334), P(0x0a338), + P(0x0a33c), P(0x0a340), P(0x0a344), P(0x0a348), P(0x0a34c), + P(0x0a350), P(0x0a354), P(0x07838), P(0x07824), P(0x0786c), + P(0x07820), P(0x0a274), P(0x0a278), P(0x0a27c), P(0x0a394), + P(0x0a398), P(0x0a3dc), P(0x0a3e0) +}; + +static const uint32_t ar9271_tx_gain_vals_2g[] = { + 0x00000000, 0x00009200, 0x00010208, 0x00019608, 0x0001e610, + 0x0002d6d0, 0x00039758, 0x0003b759, 0x0003d75a, 0x0004175c, + 0x0004575e, 0x0004979f, 0x0004d7df, 0x000368de, 0x0003891e, + 0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, + 0x0003e9df, 0x0003e9df, 0x00000029, 0x00d8abff, 0x48609eb4, + 0x00000c04, 0x0a218652, 0x3bdef7bd, 0x050e83bd, 0x3bdef7bd, + 0x000003bd, 0x3bdef7bd, 0x000003bd +}; + +static const struct athn_gain ar9271_tx_gain = { + nitems(ar9271_tx_gain_regs), + ar9271_tx_gain_regs, + NULL, /* 2GHz only. */ + ar9271_tx_gain_vals_2g +}; + +static const uint32_t ar9271_tx_gain_high_power_vals_2g[] = { + 0x00010000, 0x00016200, 0x00018201, 0x0001b240, 0x0001d241, + 0x0001f600, 0x00022800, 0x00026802, 0x0002b805, 0x0002ea41, + 0x00038b00, 0x0003ab40, 0x0003cd80, 0x000368de, 0x0003891e, + 0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, + 0x0003e9df, 0x0003e9df, 0x0000002b, 0x00d8a7ff, 0x08609eba, + 0x00000c00, 0x0a214652, 0x0e739ce7, 0x05018063, 0x06318c63, + 0x00000063, 0x06318c63, 0x00000063 +}; + +static const struct athn_gain ar9271_tx_gain_high_power = { + nitems(ar9271_tx_gain_regs), + ar9271_tx_gain_regs, + NULL, /* 2GHz only. */ + ar9271_tx_gain_high_power_vals_2g +}; diff --git a/sys/dev/athn/headers/athnreg.h b/sys/dev/athn/headers/athnreg.h new file mode 100644 --- /dev/null +++ b/sys/dev/athn/headers/athnreg.h @@ -0,0 +1,1499 @@ +/* $OpenBSD: athnreg.h,v 1.25 2020/04/28 06:58:09 stsp Exp $ */ + +/*- + * Copyright (c) 2009 Damien Bergamini + * Copyright (c) 2008-2009 Atheros Communications Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * MAC registers. + */ +#define AR_CR 0x0008 +#define AR_RXDP 0x000c +#define AR_CFG 0x0014 +#define AR_RXBP_THRESH 0x0018 +#define AR_MIRT 0x0020 +#define AR_IER 0x0024 +#define AR_TIMT 0x0028 +#define AR_RIMT 0x002c +#define AR_TXCFG 0x0030 +#define AR_RXCFG 0x0034 +#define AR_MIBC 0x0040 +#define AR_TOPS 0x0044 +#define AR_RXNPTO 0x0048 +#define AR_TXNPTO 0x004c +#define AR_RPGTO 0x0050 +#define AR_RPCNT 0x0054 +#define AR_MACMISC 0x0058 +#define AR_DATABUF_SIZE 0x0060 +#define AR_GTXTO 0x0064 +#define AR_GTTM 0x0068 +#define AR_CST 0x006c +#define AR_HP_RXDP 0x0074 +#define AR_LP_RXDP 0x0078 +#define AR_ISR 0x0080 +#define AR_ISR_S0 0x0084 +#define AR_ISR_S1 0x0088 +#define AR_ISR_S2 0x008c +#define AR_ISR_S3 0x0090 +#define AR_ISR_S4 0x0094 +#define AR_ISR_S5 0x0098 +#define AR_IMR 0x00a0 +#define AR_IMR_S0 0x00a4 +#define AR_IMR_S1 0x00a8 +#define AR_IMR_S2 0x00ac +#define AR_IMR_S3 0x00b0 +#define AR_IMR_S4 0x00b4 +#define AR_IMR_S5 0x00b8 +#define AR_ISR_RAC 0x00c0 +#define AR_ISR_S0_S 0x00c4 +#define AR_ISR_S1_S 0x00c8 +#define AR_DMADBG(i) (0x00e0 + (i) * 4) +#define AR_QTXDP(i) (0x0800 + (i) * 4) +#define AR_Q_STATUS_RING_START 0x0830 +#define AR_Q_STATUS_RING_END 0x0834 +#define AR_Q_TXE 0x0840 +#define AR_Q_TXD 0x0880 +#define AR_QCBRCFG(i) (0x08c0 + (i) * 4) +#define AR_QRDYTIMECFG(i) (0x0900 + (i) * 4) +#define AR_Q_ONESHOTARM_SC 0x0940 +#define AR_Q_ONESHOTARM_CC 0x0980 +#define AR_QMISC(i) (0x09c0 + (i) * 4) +#define AR_QSTS(i) (0x0a00 + (i) * 4) +#define AR_Q_RDYTIMESHDN 0x0a40 +#define AR_Q_DESC_CRCCHK 0x0a44 +#define AR_DQCUMASK(i) (0x1000 + (i) * 4) +#define AR_D_GBL_IFS_SIFS 0x1030 +#define AR_D_TXBLK_CMD 0x1038 +#define AR_DLCL_IFS(i) (0x1040 + (i) * 4) +#define AR_D_GBL_IFS_SLOT 0x1070 +#define AR_DRETRY_LIMIT(i) (0x1080 + (i) * 4) +#define AR_D_GBL_IFS_EIFS 0x10b0 +#define AR_DCHNTIME(i) (0x10c0 + (i) * 4) +#define AR_D_GBL_IFS_MISC 0x10f0 +#define AR_DMISC(i) (0x1100 + (i) * 4) +#define AR_D_SEQNUM 0x1140 +#define AR_D_FPCTL 0x1230 +#define AR_D_TXPSE 0x1270 +#define AR_D_TXSLOTMASK 0x12f0 +#define AR_MAC_SLEEP 0x1f00 +#define AR_CFG_LED 0x1f04 +#define AR_EEPROM_OFFSET(i) (0x2000 + (i) * 4) +#define AR_RC 0x4000 +#define AR_WA 0x4004 +#define AR_PM_STATE 0x4008 +#define AR_PCIE_PM_CTRL 0x4014 +#define AR_HOST_TIMEOUT 0x4018 +#define AR_EEPROM 0x401c +#define AR_SREV 0x4020 +#define AR_AHB_MODE 0x4024 +#define AR_INTR_SYNC_CAUSE 0x4028 +#define AR_INTR_SYNC_ENABLE 0x402c +#define AR_INTR_ASYNC_MASK 0x4030 +#define AR_INTR_SYNC_MASK 0x4034 +#define AR_INTR_ASYNC_CAUSE 0x4038 +#define AR_INTR_ASYNC_ENABLE 0x403c +#define AR_PCIE_SERDES 0x4040 +#define AR_PCIE_SERDES2 0x4044 +#define AR_INTR_PRIO_SYNC_ENABLE 0x40c4 +#define AR_INTR_PRIO_ASYNC_MASK 0x40c8 +#define AR_INTR_PRIO_SYNC_MASK 0x40cc +#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4 +#define AR_RTC_RC 0x7000 +#define AR_RTC_XTAL_CONTROL 0x7004 +#define AR_RTC_REG_CONTROL0 0x7008 +#define AR_RTC_REG_CONTROL1 0x700c +#define AR_RTC_PLL_CONTROL 0x7014 +#define AR_RTC_PLL_CONTROL2 0x703c +#define AR_RTC_RESET 0x7040 +#define AR_RTC_STATUS 0x7044 +#define AR_RTC_SLEEP_CLK 0x7048 +#define AR_RTC_FORCE_WAKE 0x704c +#define AR_RTC_INTR_CAUSE 0x7050 +#define AR_RTC_INTR_ENABLE 0x7054 +#define AR_RTC_INTR_MASK 0x7058 +#define AR_STA_ID0 0x8000 +#define AR_STA_ID1 0x8004 +#define AR_BSS_ID0 0x8008 +#define AR_BSS_ID1 0x800c +#define AR_BCN_RSSI_AVE 0x8010 +#define AR_TIME_OUT 0x8014 +#define AR_RSSI_THR 0x8018 +#define AR_USEC 0x801c +#define AR_RESET_TSF 0x8020 +#define AR_MAX_CFP_DUR 0x8038 +#define AR_RX_FILTER 0x803c +#define AR_MCAST_FIL0 0x8040 +#define AR_MCAST_FIL1 0x8044 +#define AR_DIAG_SW 0x8048 +#define AR_TSF_L32 0x804c +#define AR_TSF_U32 0x8050 +#define AR_TST_ADDAC 0x8054 +#define AR_DEF_ANTENNA 0x8058 +#define AR_AES_MUTE_MASK0 0x805c +#define AR_AES_MUTE_MASK1 0x8060 +#define AR_GATED_CLKS 0x8064 +#define AR_OBS_BUS_CTRL 0x8068 +#define AR_OBS_BUS_1 0x806c +#define AR_LAST_TSTP 0x8080 +#define AR_NAV 0x8084 +#define AR_RTS_OK 0x8088 +#define AR_RTS_FAIL 0x808c +#define AR_ACK_FAIL 0x8090 +#define AR_FCS_FAIL 0x8094 +#define AR_BEACON_CNT 0x8098 +#define AR_SLEEP1 0x80d4 +#define AR_SLEEP2 0x80d8 +#define AR_BSSMSKL 0x80e0 +#define AR_BSSMSKU 0x80e4 +#define AR_TPC 0x80e8 +#define AR_TFCNT 0x80ec +#define AR_RFCNT 0x80f0 +#define AR_RCCNT 0x80f4 +#define AR_CCCNT 0x80f8 +#define AR_QUIET1 0x80fc +#define AR_QUIET2 0x8100 +#define AR_TSF_PARM 0x8104 +#define AR_QOS_NO_ACK 0x8108 +#define AR_PHY_ERR 0x810c +#define AR_RXFIFO_CFG 0x8114 +#define AR_MIC_QOS_CONTROL 0x8118 +#define AR_MIC_QOS_SELECT 0x811c +#define AR_PCU_MISC 0x8120 +#define AR_FILT_OFDM 0x8124 +#define AR_FILT_CCK 0x8128 +#define AR_PHY_ERR_1 0x812c +#define AR_PHY_ERR_MASK_1 0x8130 +#define AR_PHY_ERR_2 0x8134 +#define AR_PHY_ERR_MASK_2 0x8138 +#define AR_TSFOOR_THRESHOLD 0x813c +#define AR_PHY_ERR_EIFS_MASK 0x8144 +#define AR_PHY_ERR_3 0x8168 +#define AR_PHY_ERR_MASK_3 0x816c +#define AR_BT_COEX_MODE 0x8170 +#define AR_BT_COEX_WEIGHT 0x8174 +#define AR_BT_COEX_MODE2 0x817c +#define AR_NEXT_NDP2_TIMER(i) (0x8180 + (i) * 4) +#define AR_NDP2_PERIOD(i) (0x81a0 + (i) * 4) +#define AR_NDP2_TIMER_MODE 0x81c0 +#define AR_TXSIFS 0x81d0 +#define AR_TXOP_X 0x81ec +#define AR_TXOP_0_3 0x81f0 +#define AR_TXOP_4_7 0x81f4 +#define AR_TXOP_8_11 0x81f8 +#define AR_TXOP_12_15 0x81fc +#define AR_GEN_TIMER(i) (0x8200 + (i) * 4) +#define AR_NEXT_TBTT_TIMER AR_GEN_TIMER(0) +#define AR_NEXT_DMA_BEACON_ALERT AR_GEN_TIMER(1) +#define AR_NEXT_CFP AR_GEN_TIMER(2) +#define AR_NEXT_HCF AR_GEN_TIMER(3) +#define AR_NEXT_TIM AR_GEN_TIMER(4) +#define AR_NEXT_DTIM AR_GEN_TIMER(5) +#define AR_NEXT_QUIET_TIMER AR_GEN_TIMER(6) +#define AR_NEXT_NDP_TIMER AR_GEN_TIMER(7) +#define AR_BEACON_PERIOD AR_GEN_TIMER(8) +#define AR_DMA_BEACON_PERIOD AR_GEN_TIMER(9) +#define AR_SWBA_PERIOD AR_GEN_TIMER(10) +#define AR_HCF_PERIOD AR_GEN_TIMER(11) +#define AR_TIM_PERIOD AR_GEN_TIMER(12) +#define AR_DTIM_PERIOD AR_GEN_TIMER(13) +#define AR_QUIET_PERIOD AR_GEN_TIMER(14) +#define AR_NDP_PERIOD AR_GEN_TIMER(15) +#define AR_TIMER_MODE 0x8240 +#define AR_SLP32_MODE 0x8244 +#define AR_SLP32_WAKE 0x8248 +#define AR_SLP32_INC 0x824c +#define AR_SLP_CNT 0x8250 +#define AR_SLP_CYCLE_CNT 0x8254 +#define AR_SLP_MIB_CTRL 0x8258 +#define AR_WOW_PATTERN_REG 0x825c +#define AR_WOW_COUNT_REG 0x8260 +#define AR_MAC_PCU_LOGIC_ANALYZER 0x8264 +#define AR_WOW_BCN_EN_REG 0x8270 +#define AR_WOW_BCN_TIMO_REG 0x8274 +#define AR_WOW_KEEP_ALIVE_TIMO_REG 0x8278 +#define AR_WOW_KEEP_ALIVE_REG 0x827c +#define AR_WOW_US_SCALAR_REG 0x8284 +#define AR_WOW_KEEP_ALIVE_DELAY_REG 0x8288 +#define AR_WOW_PATTERN_MATCH_REG 0x828c +#define AR_WOW_PATTERN_OFF1_REG 0x8290 +#define AR_WOW_PATTERN_OFF2_REG 0x8294 +#define AR_WOW_EXACT_REG 0x829c +#define AR_2040_MODE 0x8318 +#define AR_EXTRCCNT 0x8328 +#define AR_PCU_BA_BAR_CTRL 0x8330 +#define AR_SELFGEN_MASK 0x832c +#define AR_PCU_TXBUF_CTRL 0x8340 +#define AR_PCU_MISC_MODE2 0x8344 +#define AR_MAC_PCU_ASYNC_FIFO_REG3 0x8358 +#define AR_WOW_LENGTH1_REG 0x8360 +#define AR_WOW_LENGTH2_REG 0x8364 +#define AR_WOW_PATTERN_MATCH_LT_256B 0x8368 +#define AR_RATE_DURATION(i) (0x8700 + (i) * 4) +#define AR_KEYTABLE(i) (0x8800 + (i) * 32) +#define AR_KEYTABLE_KEY0(i) (AR_KEYTABLE(i) + 0) +#define AR_KEYTABLE_KEY1(i) (AR_KEYTABLE(i) + 4) +#define AR_KEYTABLE_KEY2(i) (AR_KEYTABLE(i) + 8) +#define AR_KEYTABLE_KEY3(i) (AR_KEYTABLE(i) + 12) +#define AR_KEYTABLE_KEY4(i) (AR_KEYTABLE(i) + 16) +#define AR_KEYTABLE_TYPE(i) (AR_KEYTABLE(i) + 20) +#define AR_KEYTABLE_MAC0(i) (AR_KEYTABLE(i) + 24) +#define AR_KEYTABLE_MAC1(i) (AR_KEYTABLE(i) + 28) + + +/* Bits for AR_CR. */ +#define AR_CR_RXE (AR_SREV_9380_20_OR_LATER(sc) ? 0x000c : 0x0004) +#define AR_CR_RXD 0x00000020 +#define AR_CR_SWI 0x00000040 + +/* Bits for AR_CFG. */ +#define AR_CFG_SWTD 0x00000001 +#define AR_CFG_SWTB 0x00000002 +#define AR_CFG_SWRD 0x00000004 +#define AR_CFG_SWRB 0x00000008 +#define AR_CFG_SWRG 0x00000010 +#define AR_CFG_AP_ADHOC_INDICATION 0x00000020 +#define AR_CFG_PHOK 0x00000100 +#define AR_CFG_EEBS 0x00000200 +#define AR_CFG_CLK_GATE_DIS 0x00000400 +#define AR_CFG_PCI_MASTER_REQ_Q_THRESH_M 0x00060000 +#define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S 17 + +/* Bits for AR_RXBP_THRESH. */ +#define AR_RXBP_THRESH_HP_M 0x0000000f +#define AR_RXBP_THRESH_HP_S 0 +#define AR_RXBP_THRESH_LP_M 0x00003f00 +#define AR_RXBP_THRESH_LP_S 8 + +/* Bits for AR_IER. */ +#define AR_IER_ENABLE 0x00000001 + +/* Bits for AR_MIRT. */ +#define AR_MIRT_RATE_THRES_M 0x0000ffff +#define AR_MIRT_RATE_THRES_S 0 + +/* Bits for AR_TIMT. */ +#define AR_TIMT_LAST_M 0x0000ffff +#define AR_TIMT_LAST_S 0 +#define AR_TIMT_FIRST_M 0xffff0000 +#define AR_TIMT_FIRST_S 16 + +/* Bits for AR_RIMT. */ +#define AR_RIMT_LAST_M 0x0000ffff +#define AR_RIMT_LAST_S 0 +#define AR_RIMT_FIRST_M 0xffff0000 +#define AR_RIMT_FIRST_S 16 + +/* Bits for AR_[TR]XCFG_DMASZ fields. */ +#define AR_DMASZ_4B 0 +#define AR_DMASZ_8B 1 +#define AR_DMASZ_16B 2 +#define AR_DMASZ_32B 3 +#define AR_DMASZ_64B 4 +#define AR_DMASZ_128B 5 +#define AR_DMASZ_256B 6 +#define AR_DMASZ_512B 7 + +/* Bits for AR_TXCFG. */ +#define AR_TXCFG_DMASZ_M 0x00000007 +#define AR_TXCFG_DMASZ_S 0 +#define AR_TXCFG_FTRIG_M 0x000003f0 +#define AR_TXCFG_FTRIG_S 4 +#define AR_TXCFG_FTRIG_IMMED ( 0 / 64) +#define AR_TXCFG_FTRIG_64B ( 64 / 64) +#define AR_TXCFG_FTRIG_128B (128 / 64) +#define AR_TXCFG_FTRIG_192B (192 / 64) +#define AR_TXCFG_FTRIG_256B (256 / 64) +#define AR_TXCFG_FTRIG_512B (512 / 64) +#define AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY 0x00000800 + +/* Bits for AR_RXCFG. */ +#define AR_RXCFG_DMASZ_M 0x00000007 +#define AR_RXCFG_DMASZ_S 0 +#define AR_RXCFG_CHIRP 0x00000008 +#define AR_RXCFG_ZLFDMA 0x00000010 + +/* Bits for AR_MIBC. */ +#define AR_MIBC_COW 0x00000001 +#define AR_MIBC_FMC 0x00000002 +#define AR_MIBC_CMC 0x00000004 +#define AR_MIBC_MCS 0x00000008 + +/* Bits for AR_TOPS. */ +#define AR_TOPS_MASK 0x0000ffff + +/* Bits for AR_RXNPTO. */ +#define AR_RXNPTO_MASK 0x000003ff + +/* Bits for AR_TXNPTO. */ +#define AR_TXNPTO_MASK 0x000003ff +#define AR_TXNPTO_QCU_MASK 0x000ffc00 + +/* Bits for AR_RPGTO. */ +#define AR_RPGTO_MASK 0x000003ff + +/* Bits for AR_RPCNT. */ +#define AR_RPCNT_MASK 0x0000001f + +/* Bits for AR_MACMISC. */ +#define AR_MACMISC_PCI_EXT_FORCE 0x00000010 +#define AR_MACMISC_DMA_OBS_M 0x000001e0 +#define AR_MACMISC_DMA_OBS_S 5 +#define AR_MACMISC_MISC_OBS_M 0x00000e00 +#define AR_MACMISC_MISC_OBS_S 9 +#define AR_MACMISC_MISC_OBS_BUS_LSB_M 0x00007000 +#define AR_MACMISC_MISC_OBS_BUS_LSB_S 12 +#define AR_MACMISC_MISC_OBS_BUS_MSB_M 0x00038000 +#define AR_MACMISC_MISC_OBS_BUS_MSB_S 15 + +/* Bits for AR_GTXTO. */ +#define AR_GTXTO_TIMEOUT_COUNTER_M 0x0000ffff +#define AR_GTXTO_TIMEOUT_COUNTER_S 0 +#define AR_GTXTO_TIMEOUT_LIMIT_M 0xffff0000 +#define AR_GTXTO_TIMEOUT_LIMIT_S 16 + +/* Bits for AR_GTTM. */ +#define AR_GTTM_USEC 0x00000001 +#define AR_GTTM_IGNORE_IDLE 0x00000002 +#define AR_GTTM_RESET_IDLE 0x00000004 +#define AR_GTTM_CST_USEC 0x00000008 + +/* Bits for AR_CST. */ +#define AR_CST_TIMEOUT_COUNTER_M 0x0000ffff +#define AR_CST_TIMEOUT_COUNTER_S 0 +#define AR_CST_TIMEOUT_LIMIT_M 0xffff0000 +#define AR_CST_TIMEOUT_LIMIT_S 16 + +/* Bits for AR_ISR. */ +#define AR_ISR_RXOK 0x00000001 +#define AR_ISR_HP_RXOK 0x00000001 +#define AR_ISR_RXDESC 0x00000002 +#define AR_ISR_LP_RXOK 0x00000002 +#define AR_ISR_RXERR 0x00000004 +#define AR_ISR_RXNOPKT 0x00000008 +#define AR_ISR_RXEOL 0x00000010 +#define AR_ISR_RXORN 0x00000020 +#define AR_ISR_TXOK 0x00000040 +#define AR_ISR_TXDESC 0x00000080 +#define AR_ISR_TXERR 0x00000100 +#define AR_ISR_TXNOPKT 0x00000200 +#define AR_ISR_TXEOL 0x00000400 +#define AR_ISR_TXURN 0x00000800 +#define AR_ISR_MIB 0x00001000 +#define AR_ISR_SWI 0x00002000 +#define AR_ISR_RXPHY 0x00004000 +#define AR_ISR_RXKCM 0x00008000 +#define AR_ISR_SWBA 0x00010000 +#define AR_ISR_BRSSI 0x00020000 +#define AR_ISR_BMISS 0x00040000 +#define AR_ISR_TXMINTR 0x00080000 +#define AR_ISR_BNR 0x00100000 +#define AR_ISR_RXCHIRP 0x00200000 +#define AR_ISR_BCNMISC 0x00800000 +#define AR_ISR_TIM 0x00800000 +#define AR_ISR_RXMINTR 0x01000000 +#define AR_ISR_QCBROVF 0x02000000 +#define AR_ISR_QCBRURN 0x04000000 +#define AR_ISR_QTRIG 0x08000000 +#define AR_ISR_GENTMR 0x10000000 +#define AR_ISR_TXINTM 0x40000000 +#define AR_ISR_RXINTM 0x80000000 + +/* Bits for AR_ISR_S0. */ +#define AR_ISR_S0_QCU_TXOK_M 0x000003ff +#define AR_ISR_S0_QCU_TXOK_S 0 +#define AR_ISR_S0_QCU_TXDESC_M 0x03ff0000 +#define AR_ISR_S0_QCU_TXDESC_S 16 + +/* Bits for AR_ISR_S1. */ +#define AR_ISR_S1_QCU_TXERR_M 0x000003ff +#define AR_ISR_S1_QCU_TXERR_S 0 +#define AR_ISR_S1_QCU_TXEOL_M 0x03ff0000 +#define AR_ISR_S1_QCU_TXEOL_S 16 + +/* Bits for AR_ISR_S2. */ +#define AR_ISR_S2_QCU_TXURN_M 0x000003ff +#define AR_ISR_S2_QCU_TXURN_S 0 +#define AR_ISR_S2_BB_WATCHDOG 0x00010000 +#define AR_ISR_S2_CST 0x00400000 +#define AR_ISR_S2_GTT 0x00800000 +#define AR_ISR_S2_TIM 0x01000000 +#define AR_ISR_S2_CABEND 0x02000000 +#define AR_ISR_S2_DTIMSYNC 0x04000000 +#define AR_ISR_S2_BCNTO 0x08000000 +#define AR_ISR_S2_CABTO 0x10000000 +#define AR_ISR_S2_DTIM 0x20000000 +#define AR_ISR_S2_TSFOOR 0x40000000 +#define AR_ISR_S2_TBTT_TIME 0x80000000 + +/* Bits for AR_ISR_S3. */ +#define AR_ISR_S3_QCU_QCBROVF_M 0x000003ff +#define AR_ISR_S3_QCU_QCBROVF_S 0 +#define AR_ISR_S3_QCU_QCBRURN_M 0x03ff0000 +#define AR_ISR_S3_QCU_QCBRURN_S 0 + +/* Bits for AR_ISR_S4. */ +#define AR_ISR_S4_QCU_QTRIG_M 0x000003ff +#define AR_ISR_S4_QCU_QTRIG_S 0 + +/* Bits for AR_ISR_S5. */ +#define AR_ISR_S5_TIMER_TRIG_M 0x000000ff +#define AR_ISR_S5_TIMER_TRIG_S 0 +#define AR_ISR_S5_TIMER_THRESH_M 0x0007fe00 +#define AR_ISR_S5_TIMER_THRESH_S 9 +#define AR_ISR_S5_TIM_TIMER 0x00000010 +#define AR_ISR_S5_DTIM_TIMER 0x00000020 +#define AR_ISR_S5_GENTIMER_TRIG_M 0x0000ff80 +#define AR_ISR_S5_GENTIMER_TRIG_S 0 +#define AR_ISR_S5_GENTIMER_THRESH_M 0xff800000 +#define AR_ISR_S5_GENTIMER_THRESH_S 16 + +/* Bits for AR_IMR. */ +#define AR_IMR_RXOK 0x00000001 +#define AR_IMR_HP_RXOK 0x00000001 +#define AR_IMR_RXDESC 0x00000002 +#define AR_IMR_LP_RXOK 0x00000002 +#define AR_IMR_RXERR 0x00000004 +#define AR_IMR_RXNOPKT 0x00000008 +#define AR_IMR_RXEOL 0x00000010 +#define AR_IMR_RXORN 0x00000020 +#define AR_IMR_TXOK 0x00000040 +#define AR_IMR_TXDESC 0x00000080 +#define AR_IMR_TXERR 0x00000100 +#define AR_IMR_TXNOPKT 0x00000200 +#define AR_IMR_TXEOL 0x00000400 +#define AR_IMR_TXURN 0x00000800 +#define AR_IMR_MIB 0x00001000 +#define AR_IMR_SWI 0x00002000 +#define AR_IMR_RXPHY 0x00004000 +#define AR_IMR_RXKCM 0x00008000 +#define AR_IMR_SWBA 0x00010000 +#define AR_IMR_BRSSI 0x00020000 +#define AR_IMR_BMISS 0x00040000 +#define AR_IMR_TXMINTR 0x00080000 +#define AR_IMR_BNR 0x00100000 +#define AR_IMR_RXCHIRP 0x00200000 +#define AR_IMR_BCNMISC 0x00800000 +#define AR_IMR_TIM 0x00800000 +#define AR_IMR_RXMINTR 0x01000000 +#define AR_IMR_QCBROVF 0x02000000 +#define AR_IMR_QCBRURN 0x04000000 +#define AR_IMR_QTRIG 0x08000000 +#define AR_IMR_GENTMR 0x10000000 +#define AR_IMR_TXINTM 0x40000000 +#define AR_IMR_RXINTM 0x80000000 + +#define AR_IMR_DEFAULT \ + (AR_IMR_TXERR | AR_IMR_TXURN | AR_IMR_RXERR | \ + AR_IMR_RXORN | AR_IMR_BCNMISC | AR_IMR_RXINTM | \ + AR_IMR_RXMINTR | AR_IMR_TXOK) +#define AR_IMR_HOSTAP (AR_IMR_DEFAULT | AR_IMR_MIB) + +/* Bits for AR_IMR_S0. */ +#define AR_IMR_S0_QCU_TXOK(qid) (1 << (qid)) +#define AR_IMR_S0_QCU_TXDESC(qid) (1 << (16 + (qid))) + +/* Bits for AR_IMR_S1. */ +#define AR_IMR_S1_QCU_TXERR(qid) (1 << (qid)) +#define AR_IMR_S1_QCU_TXEOL(qid) (1 << (16 + (qid))) + +/* Bits for AR_IMR_S2. */ +#define AR_IMR_S2_QCU_TXURN(qid) (1 << (qid)) +#define AR_IMR_S2_CST 0x00400000 +#define AR_IMR_S2_GTT 0x00800000 +#define AR_IMR_S2_TIM 0x01000000 +#define AR_IMR_S2_CABEND 0x02000000 +#define AR_IMR_S2_DTIMSYNC 0x04000000 +#define AR_IMR_S2_BCNTO 0x08000000 +#define AR_IMR_S2_CABTO 0x10000000 +#define AR_IMR_S2_DTIM 0x20000000 +#define AR_IMR_S2_TSFOOR 0x40000000 + +/* Bits for AR_IMR_S3. */ +#define AR_IMR_S3_QCU_QCBROVF(qid) (1 << (qid)) +#define AR_IMR_S3_QCU_QCBRURN(qid) (1 << (16 + (qid))) + +/* Bits for AR_IMR_S4. */ +#define AR_IMR_S4_QCU_QTRIG(qid) (1 << (qid)) + +/* Bits for AR_IMR_S5. */ +#define AR_IMR_S5_TIM_TIMER 0x00000010 +#define AR_IMR_S5_DTIM_TIMER 0x00000020 +#define AR_IMR_S5_TIMER_TRIG_M 0x000000ff +#define AR_IMR_S5_TIMER_TRIG_S 0 +#define AR_IMR_S5_TIMER_THRESH_M 0x0000ff00 +#define AR_IMR_S5_TIMER_THRESH_S 0 + +#define AR_NUM_QCU 10 +#define AR_QCU(x) (1 << (x)) + +/* Bits for AR_Q_TXE. */ +#define AR_Q_TXE_M 0x000003ff +#define AR_Q_TXE_S 0 + +/* Bits for AR_Q_TXD. */ +#define AR_Q_TXD_M 0x000003ff +#define AR_Q_TXD_S 0 + +/* Bits for AR_QCBRCFG_*. */ +#define AR_Q_CBRCFG_INTERVAL_M 0x00ffffff +#define AR_Q_CBRCFG_INTERVAL_S 0 +#define AR_Q_CBRCFG_OVF_THRESH_M 0xff000000 +#define AR_Q_CBRCFG_OVF_THRESH_S 24 + +/* Bits for AR_QRDYTIMECFG_*. */ +#define AR_Q_RDYTIMECFG_DURATION_M 0x00ffffff +#define AR_Q_RDYTIMECFG_DURATION_S 0 +#define AR_Q_RDYTIMECFG_EN 0x01000000 + +/* Bits for AR_QMISC_*. */ +#define AR_Q_MISC_FSP_M 0x0000000f +#define AR_Q_MISC_FSP_S 0 +#define AR_Q_MISC_FSP_ASAP 0 +#define AR_Q_MISC_FSP_CBR 1 +#define AR_Q_MISC_FSP_DBA_GATED 2 +#define AR_Q_MISC_FSP_TIM_GATED 3 +#define AR_Q_MISC_FSP_BEACON_SENT_GATED 4 +#define AR_Q_MISC_FSP_BEACON_RCVD_GATED 5 +#define AR_Q_MISC_ONE_SHOT_EN 0x00000010 +#define AR_Q_MISC_CBR_INCR_DIS1 0x00000020 +#define AR_Q_MISC_CBR_INCR_DIS0 0x00000040 +#define AR_Q_MISC_BEACON_USE 0x00000080 +#define AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN 0x00000100 +#define AR_Q_MISC_RDYTIME_EXP_POLICY 0x00000200 +#define AR_Q_MISC_RESET_CBR_EXP_CTR 0x00000400 +#define AR_Q_MISC_DCU_EARLY_TERM_REQ 0x00000800 + +/* Bits for AR_QSTS_*. */ +#define AR_Q_STS_PEND_FR_CNT_M 0x00000003 +#define AR_Q_STS_PEND_FR_CNT_S 0 +#define AR_Q_STS_CBR_EXP_CNT_M 0x0000ff00 +#define AR_Q_STS_CBR_EXP_CNT_S 8 + +/* Bits for AR_Q_DESC_CRCCHK. */ +#define AR_Q_DESC_CRCCHK_EN 0x00000001 + +#define AR_NUM_DCU 10 +#define AR_DCU(x) (1 << (x)) + +/* Bits for AR_D_QCUMASK_*. */ +#define AR_D_QCUMASK_M 0x000003ff +#define AR_D_QCUMASK_S 0 + +/* Bits for AR_D_GBL_IFS_SIFS. */ +#define AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR 0x000003ab + +/* Bits for AR_D_TXBLK_CMD. */ +#define AR_D_TXBLK_WRITE_BITMASK_M 0x0000ffff +#define AR_D_TXBLK_WRITE_BITMASK_S 0 +#define AR_D_TXBLK_WRITE_SLICE_M 0x000f0000 +#define AR_D_TXBLK_WRITE_SLICE_S 16 +#define AR_D_TXBLK_WRITE_DCU_M 0x00f00000 +#define AR_D_TXBLK_WRITE_DCU_S 20 +#define AR_D_TXBLK_WRITE_COMMAND_M 0x0f000000 +#define AR_D_TXBLK_WRITE_COMMAND_S 24 + +/* Bits for AR_DLCL_IFS. */ +#define AR_D_LCL_IFS_CWMIN_M 0x000003ff +#define AR_D_LCL_IFS_CWMIN_S 0 +#define AR_D_LCL_IFS_CWMAX_M 0x000ffc00 +#define AR_D_LCL_IFS_CWMAX_S 10 +#define AR_D_LCL_IFS_AIFS_M 0x0ff00000 +#define AR_D_LCL_IFS_AIFS_S 20 + +/* Bits for AR_D_GBL_IFS_SLOT. */ +#define AR_D_GBL_IFS_SLOT_M 0x0000ffff +#define AR_D_GBL_IFS_SLOT_S 0 +#define AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR 0x00000420 + +/* Bits for AR_DRETRY_LIMIT_*. */ +#define AR_D_RETRY_LIMIT_FR_SH_M 0x0000000f +#define AR_D_RETRY_LIMIT_FR_SH_S 0 +#define AR_D_RETRY_LIMIT_STA_SH_M 0x00003f00 +#define AR_D_RETRY_LIMIT_STA_SH_S 8 +#define AR_D_RETRY_LIMIT_STA_LG_M 0x000fc000 +#define AR_D_RETRY_LIMIT_STA_LG_S 14 + +/* Bits for AR_D_GBL_IFS_EIFS. */ +#define AR_D_GBL_IFS_EIFS_M 0x0000ffff +#define AR_D_GBL_IFS_EIFS_S 0 +#define AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR 0x0000a5eb + +/* Bits for AR_DCHNTIME_*. */ +#define AR_D_CHNTIME_DUR_M 0x000fffff +#define AR_D_CHNTIME_DUR_S 0 +#define AR_D_CHNTIME_EN 0x00100000 + +/* Bits for AR_D_GBL_IFS_MISC. */ +#define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL 0x00000007 +#define AR_D_GBL_IFS_MISC_TURBO_MODE 0x00000008 +#define AR_D_GBL_IFS_MISC_USEC_DURATION 0x000ffc00 +#define AR_D_GBL_IFS_MISC_DCU_ARBITER_DLY 0x00300000 +#define AR_D_GBL_IFS_MISC_RANDOM_LFSR_SLICE_DIS 0x01000000 +#define AR_D_GBL_IFS_MISC_SLOT_XMIT_WIND_LEN 0x06000000 +#define AR_D_GBL_IFS_MISC_FORCE_XMIT_SLOT_BOUND 0x08000000 +#define AR_D_GBL_IFS_MISC_IGNORE_BACKOFF 0x10000000 + +/* Bits for AR_DMISC_*. */ +#define AR_D_MISC_BKOFF_THRESH_M 0x0000003f +#define AR_D_MISC_BKOFF_THRESH_S 0 +#define AR_D_MISC_RETRY_CNT_RESET_EN 0x00000040 +#define AR_D_MISC_CW_RESET_EN 0x00000080 +#define AR_D_MISC_FRAG_WAIT_EN 0x00000100 +#define AR_D_MISC_FRAG_BKOFF_EN 0x00000200 +#define AR_D_MISC_CW_BKOFF_EN 0x00001000 +#define AR_D_MISC_VIR_COL_HANDLING_M 0x0000c000 +#define AR_D_MISC_VIR_COL_HANDLING_S 14 +#define AR_D_MISC_VIR_COL_HANDLING_DEFAULT 0 +#define AR_D_MISC_VIR_COL_HANDLING_IGNORE 1 +#define AR_D_MISC_BEACON_USE 0x00010000 +#define AR_D_MISC_ARB_LOCKOUT_CNTRL_M 0x00060000 +#define AR_D_MISC_ARB_LOCKOUT_CNTRL_S 17 +#define AR_D_MISC_ARB_LOCKOUT_CNTRL_NONE 0 +#define AR_D_MISC_ARB_LOCKOUT_CNTRL_INTRA_FR 1 +#define AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL 2 +#define AR_D_MISC_ARB_LOCKOUT_IGNORE 0x00080000 +#define AR_D_MISC_SEQ_NUM_INCR_DIS 0x00100000 +#define AR_D_MISC_POST_FR_BKOFF_DIS 0x00200000 +#define AR_D_MISC_VIT_COL_CW_BKOFF_EN 0x00400000 +#define AR_D_MISC_BLOWN_IFS_RETRY_EN 0x00800000 + +/* Bits for AR_D_FPCTL. */ +#define AR_D_FPCTL_DCU_M 0x0000000f +#define AR_D_FPCTL_DCU_S 0 +#define AR_D_FPCTL_PREFETCH_EN 0x00000010 +#define AR_D_FPCTL_BURST_PREFETCH_M 0x00007fe0 +#define AR_D_FPCTL_BURST_PREFETCH_S 5 + +/* Bits for AR_D_TXPSE. */ +#define AR_D_TXPSE_CTRL_M 0x000003ff +#define AR_D_TXPSE_CTRL_S 0 +#define AR_D_TXPSE_STATUS 0x00010000 + +/* Bits for AR_D_TXSLOTMASK. */ +#define AR_D_TXSLOTMASK_NUM 0x0000000f + +/* Bits for AR_MAC_SLEEP. */ +#define AR_MAC_SLEEP_MAC_ASLEEP 0x00000001 + +/* Bits for AR_CFG_LED. */ +#define AR_CFG_SCLK_RATE_IND_M 0x00000003 +#define AR_CFG_SCLK_RATE_IND_S 0 +#define AR_CFG_SCLK_32MHZ 0 +#define AR_CFG_SCLK_4MHZ 1 +#define AR_CFG_SCLK_1MHZ 2 +#define AR_CFG_SCLK_32KHZ 3 +#define AR_CFG_LED_BLINK_SLOW 0x00000008 +#define AR_CFG_LED_BLINK_THRESH_SEL_M 0x00000070 +#define AR_CFG_LED_BLINK_THRESH_SEL_S 4 +#define AR_CFG_LED_MODE_SEL_M 0x00000380 +#define AR_CFG_LED_MODE_SEL_S 7 +#define AR_CFG_LED_POWER_M 0x00000280 +#define AR_CFG_LED_POWER_S 7 +#define AR_CFG_LED_NETWORK_M 0x00000300 +#define AR_CFG_LED_NETWORK_S 7 +#define AR_CFG_LED_MODE_PROP 0 +#define AR_CFG_LED_MODE_RPROP 1 +#define AR_CFG_LED_MODE_SPLIT 2 +#define AR_CFG_LED_MODE_RAND 3 +#define AR_CFG_LED_MODE_POWER_OFF 4 +#define AR_CFG_LED_MODE_POWER_ON 5 +#define AR_CFG_LED_MODE_NETWORK_OFF 4 +#define AR_CFG_LED_MODE_NETWORK_ON 6 +#define AR_CFG_LED_ASSOC_CTL_M 0x00000c00 +#define AR_CFG_LED_ASSOC_CTL_S 10 +#define AR_CFG_LED_ASSOC_NONE 0 +#define AR_CFG_LED_ASSOC_ACTIVE 1 +#define AR_CFG_LED_ASSOC_PENDING 2 + +/* Bit for AR_RC. */ +#define AR_RC_AHB 0x00000001 +#define AR_RC_APB 0x00000002 +#define AR_RC_HOSTIF 0x00000100 + +/* Bits for AR_WA. */ +#define AR5416_WA_DEFAULT 0x0000073f +#define AR9280_WA_DEFAULT 0x0040073b +#define AR9285_WA_DEFAULT 0x004a050b +#define AR_WA_UNTIE_RESET_EN 0x00008000 +#define AR_WA_RESET_EN 0x00040000 +#define AR_WA_ANALOG_SHIFT 0x00100000 +#define AR_WA_POR_SHORT 0x00200000 + +/* Bits for AR_PM_STATE. */ +#define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000 + +/* Bits for AR_PCIE_PM_CTRL. */ +#define AR_PCIE_PM_CTRL_ENA 0x00080000 + +/* Bits for AR_HOST_TIMEOUT. */ +#define AR_HOST_TIMEOUT_APB_CNTR_M 0x0000ffff +#define AR_HOST_TIMEOUT_APB_CNTR_S 0 +#define AR_HOST_TIMEOUT_LCL_CNTR_M 0xffff0000 +#define AR_HOST_TIMEOUT_LCL_CNTR_S 16 + +/* Bits for AR_EEPROM. */ +#define AR_EEPROM_ABSENT 0x00000100 +#define AR_EEPROM_CORRUPT 0x00000200 +#define AR_EEPROM_PROT_MASK_M 0x03fffc00 +#define AR_EEPROM_PROT_MASK_S 10 + +/* Bits for AR_SREV. */ +#define AR_SREV_ID_M 0x000000ff +#define AR_SREV_ID_S 0 +#define AR_SREV_REVISION_M 0x00000007 +#define AR_SREV_REVISION_S 0 +#define AR_SREV_VERSION_M 0x000000f0 +#define AR_SREV_VERSION_S 4 +#define AR_SREV_VERSION2_M 0xfffc0000 +#define AR_SREV_VERSION2_S 12 /* XXX Hack. */ +#define AR_SREV_TYPE2_M 0x0003f000 +#define AR_SREV_TYPE2_S 12 +#define AR_SREV_TYPE2_CHAIN 0x00001000 +#define AR_SREV_TYPE2_HOST_MODE 0x00002000 +#define AR_SREV_REVISION2_M 0x00000f00 +#define AR_SREV_REVISION2_S 8 +#define AR_SREV_VERSION_5416_PCI 0x00d +#define AR_SREV_VERSION_5416_PCIE 0x00c +#define AR_SREV_REVISION_5416_10 0 +#define AR_SREV_REVISION_5416_20 1 +#define AR_SREV_REVISION_5416_22 2 +#define AR_SREV_VERSION_9100 0x014 +#define AR_SREV_VERSION_9160 0x040 +#define AR_SREV_REVISION_9160_10 0 +#define AR_SREV_REVISION_9160_11 1 +#define AR_SREV_VERSION_9280 0x080 +#define AR_SREV_REVISION_9280_10 0 +#define AR_SREV_REVISION_9280_20 1 +#define AR_SREV_REVISION_9280_21 2 +#define AR_SREV_VERSION_9285 0x0c0 +#define AR_SREV_REVISION_9285_10 0 +#define AR_SREV_REVISION_9285_11 1 +#define AR_SREV_REVISION_9285_12 2 +#define AR_SREV_VERSION_9271 0x140 +#define AR_SREV_REVISION_9271_10 0 +#define AR_SREV_REVISION_9271_11 1 +#define AR_SREV_VERSION_9287 0x180 +#define AR_SREV_REVISION_9287_10 0 +#define AR_SREV_REVISION_9287_11 1 +#define AR_SREV_REVISION_9287_12 2 +#define AR_SREV_REVISION_9287_13 3 +#define AR_SREV_VERSION_9380 0x1c0 +#define AR_SREV_REVISION_9380_10 0 +#define AR_SREV_REVISION_9380_20 2 +#define AR_SREV_VERSION_9485 0x240 +#define AR_SREV_REVISION_9485_10 0 + +/* Bits for AR_AHB_MODE. */ +#define AR_AHB_EXACT_WR_EN 0x00000000 +#define AR_AHB_BUF_WR_EN 0x00000001 +#define AR_AHB_EXACT_RD_EN 0x00000000 +#define AR_AHB_CACHELINE_RD_EN 0x00000002 +#define AR_AHB_PREFETCH_RD_EN 0x00000004 +#define AR_AHB_PAGE_SIZE_1K 0x00000000 +#define AR_AHB_PAGE_SIZE_2K 0x00000008 +#define AR_AHB_PAGE_SIZE_4K 0x00000010 +#define AR_AHB_CUSTOM_BURST_M 0x000000c0 +#define AR_AHB_CUSTOM_BURST_S 6 +#define AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL 3 + +/* Bits for AR_INTR_SYNC_CAUSE. */ +#define AR_INTR_SYNC_RTC_IRQ 0x00000001 +#define AR_INTR_SYNC_MAC_IRQ 0x00000002 +#define AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS 0x00000004 +#define AR_INTR_SYNC_APB_TIMEOUT 0x00000008 +#define AR_INTR_SYNC_PCI_MODE_CONFLICT 0x00000010 +#define AR_INTR_SYNC_HOST1_FATAL 0x00000020 +#define AR_INTR_SYNC_HOST1_PERR 0x00000040 +#define AR_INTR_SYNC_TRCV_FIFO_PERR 0x00000080 +#define AR_INTR_SYNC_RADM_CPL_EP 0x00000100 +#define AR_INTR_SYNC_RADM_CPL_DLLP_ABORT 0x00000200 +#define AR_INTR_SYNC_RADM_CPL_TLP_ABORT 0x00000400 +#define AR_INTR_SYNC_RADM_CPL_ECRC_ERR 0x00000800 +#define AR_INTR_SYNC_RADM_CPL_TIMEOUT 0x00001000 +#define AR_INTR_SYNC_LOCAL_TIMEOUT 0x00002000 +#define AR_INTR_SYNC_PM_ACCESS 0x00004000 +#define AR_INTR_SYNC_MAC_AWAKE 0x00008000 +#define AR_INTR_SYNC_MAC_ASLEEP 0x00010000 +#define AR_INTR_SYNC_MAC_SLEEP_ACCESS 0x00020000 +#define AR_INTR_SYNC_ALL 0x0003ffff +#define AR_INTR_SYNC_GPIO_PIN(i) (1 << (18 + (i))) + +#define AR_INTR_SYNC_DEFAULT \ + (AR_INTR_SYNC_HOST1_FATAL | \ + AR_INTR_SYNC_HOST1_PERR | \ + AR_INTR_SYNC_RADM_CPL_EP | \ + AR_INTR_SYNC_RADM_CPL_DLLP_ABORT | \ + AR_INTR_SYNC_RADM_CPL_TLP_ABORT | \ + AR_INTR_SYNC_RADM_CPL_ECRC_ERR | \ + AR_INTR_SYNC_RADM_CPL_TIMEOUT | \ + AR_INTR_SYNC_LOCAL_TIMEOUT | \ + AR_INTR_SYNC_MAC_SLEEP_ACCESS) + +/* Bits for AR_INTR_ASYNC_CAUSE. */ +#define AR_INTR_RTC_IRQ 0x00000001 +#define AR_INTR_MAC_IRQ 0x00000002 +#define AR_INTR_EEP_PROT_ACCESS 0x00000004 +#define AR_INTR_MAC_AWAKE 0x00020000 +#define AR_INTR_MAC_ASLEEP 0x00040000 +#define AR_INTR_GPIO_PIN(i) (1 << (18 + (i))) +#define AR_INTR_SPURIOUS 0xffffffff + +/* Bits for AR_GPIO_OE_OUT. */ +#define AR_GPIO_OE_OUT_DRV_M 0x00000003 +#define AR_GPIO_OE_OUT_DRV_S 0 +#define AR_GPIO_OE_OUT_DRV_NO 0 +#define AR_GPIO_OE_OUT_DRV_LOW 1 +#define AR_GPIO_OE_OUT_DRV_HI 2 +#define AR_GPIO_OE_OUT_DRV_ALL 3 + +/* Bits for AR_GPIO_INTR_POL. */ +#define AR_GPIO_INTR_POL_PIN(i) (1 << (i)) + +/* Bits for AR_GPIO_INPUT_EN_VAL. */ +#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004 +#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008 +#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_DEF 0x00000010 +#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF 0x00000080 +#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB 0x00000400 +#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB 0x00001000 +#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB 0x00008000 +#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000 +#define AR_GPIO_JTAG_DISABLE 0x00020000 + +/* Bits for AR_GPIO_INPUT_MUX1. */ +#define AR_GPIO_INPUT_MUX1_BT_PRIORITY_M 0x00000f00 +#define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8 +#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_M 0x000f0000 +#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16 + +/* Bits for AR_GPIO_INPUT_MUX2. */ +#define AR_GPIO_INPUT_MUX2_CLK25_M 0x0000000f +#define AR_GPIO_INPUT_MUX2_CLK25_S 0 +#define AR_GPIO_INPUT_MUX2_RFSILENT_M 0x000000f0 +#define AR_GPIO_INPUT_MUX2_RFSILENT_S 4 +#define AR_GPIO_INPUT_MUX2_RTC_RESET_M 0x00000f00 +#define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8 + +/* Bits for AR_GPIO_OUTPUT_MUX[1-3]. */ +#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0 +#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1 +#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2 +#define AR_GPIO_OUTPUT_MUX_AS_TX_FRAME 3 +#define AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL 4 +#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5 +#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6 + +/* Bits for AR_EEPROM_STATUS_DATA. */ +#define AR_EEPROM_STATUS_DATA_VAL_M 0x0000ffff +#define AR_EEPROM_STATUS_DATA_VAL_S 0 +#define AR_EEPROM_STATUS_DATA_BUSY 0x00010000 +#define AR_EEPROM_STATUS_DATA_BUSY_ACCESS 0x00020000 +#define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000 +#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000 + +/* Bits for AR_PCIE_MSI. */ +#define AR_PCIE_MSI_ENABLE 0x00000001 + +/* Bits for AR_RTC_RC. */ +#define AR_RTC_RC_MAC_WARM 0x00000001 +#define AR_RTC_RC_MAC_COLD 0x00000002 +#define AR_RTC_RC_COLD_RESET 0x00000004 +#define AR_RTC_RC_WARM_RESET 0x00000008 + +/* Bits for AR_RTC_REG_CONTROL1. */ +#define AR_RTC_REG_CONTROL1_SWREG_PROGRAM 0x00000001 + +/* Bits for AR_RTC_PLL_CONTROL. */ +#define AR_RTC_PLL_DIV_M 0x0000001f +#define AR_RTC_PLL_DIV_S 0 +#define AR_RTC_PLL_DIV2 0x00000020 +#define AR_RTC_PLL_REFDIV_5 0x000000c0 +#define AR_RTC_PLL_CLKSEL_M 0x00000300 +#define AR_RTC_PLL_CLKSEL_S 8 +#define AR_RTC_9160_PLL_DIV_M 0x000003ff +#define AR_RTC_9160_PLL_DIV_S 0 +#define AR_RTC_9160_PLL_REFDIV_M 0x00003c00 +#define AR_RTC_9160_PLL_REFDIV_S 10 +#define AR_RTC_9160_PLL_CLKSEL_M 0x0000c000 +#define AR_RTC_9160_PLL_CLKSEL_S 14 + +/* Bits for AR_RTC_RESET. */ +#define AR_RTC_RESET_EN 0x00000001 + +/* Bits for AR_RTC_STATUS. */ +#define AR_RTC_STATUS_M 0x0000000f +#define AR_RTC_STATUS_S 0 +#define AR_RTC_STATUS_SHUTDOWN 0x00000001 +#define AR_RTC_STATUS_ON 0x00000002 +#define AR_RTC_STATUS_SLEEP 0x00000004 +#define AR_RTC_STATUS_WAKEUP 0x00000008 + +/* Bits for AR_RTC_SLEEP_CLK. */ +#define AR_RTC_FORCE_DERIVED_CLK 0x00000002 +#define AR_RTC_FORCE_SWREG_PRD 0x00000004 + +/* Bits for AR_RTC_FORCE_WAKE. */ +#define AR_RTC_FORCE_WAKE_EN 0x00000001 +#define AR_RTC_FORCE_WAKE_ON_INT 0x00000002 + +/* Bits for AR_STA_ID1. */ +#define AR_STA_ID1_SADH_M 0x0000ffff +#define AR_STA_ID1_SADH_S 0 +#define AR_STA_ID1_STA_AP 0x00010000 +#define AR_STA_ID1_ADHOC 0x00020000 +#define AR_STA_ID1_PWR_SAV 0x00040000 +#define AR_STA_ID1_KSRCHDIS 0x00080000 +#define AR_STA_ID1_PCF 0x00100000 +#define AR_STA_ID1_USE_DEFANT 0x00200000 +#define AR_STA_ID1_DEFANT_UPDATE 0x00400000 +#define AR_STA_ID1_RTS_USE_DEF 0x00800000 +#define AR_STA_ID1_ACKCTS_6MB 0x01000000 +#define AR_STA_ID1_BASE_RATE_11B 0x02000000 +#define AR_STA_ID1_SECTOR_SELF_GEN 0x04000000 +#define AR_STA_ID1_CRPT_MIC_ENABLE 0x08000000 +#define AR_STA_ID1_KSRCH_MODE 0x10000000 +#define AR_STA_ID1_PRESERVE_SEQNUM 0x20000000 +#define AR_STA_ID1_CBCIV_ENDIAN 0x40000000 +#define AR_STA_ID1_MCAST_KSRCH 0x80000000 + +/* Bits for AR_BSS_ID1. */ +#define AR_BSS_ID1_U16_M 0x0000ffff +#define AR_BSS_ID1_U16_S 0 +#define AR_BSS_ID1_AID_M 0x07ff0000 +#define AR_BSS_ID1_AID_S 16 + +/* Bits for AR_TIME_OUT. */ +#define AR_TIME_OUT_ACK_M 0x00003fff +#define AR_TIME_OUT_ACK_S 0 +#define AR_TIME_OUT_CTS_M 0x3fff0000 +#define AR_TIME_OUT_CTS_S 16 +#define AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR 0x16001d56 + +/* Bits for AR_RSSI_THR. */ +#define AR_RSSI_THR_M 0x000000ff +#define AR_RSSI_THR_S 0 +#define AR_RSSI_THR_BM_THR_M 0x0000ff00 +#define AR_RSSI_THR_BM_THR_S 8 +#define AR_RSSI_BCN_WEIGHT_M 0x1f000000 +#define AR_RSSI_BCN_WEIGHT_S 24 +#define AR_RSSI_BCN_RSSI_RST 0x20000000 + +/* Bits for AR_USEC. */ +#define AR_USEC_USEC_M 0x0000007f +#define AR_USEC_USEC_S 0 +#define AR_USEC_TX_LAT_M 0x007fc000 +#define AR_USEC_TX_LAT_S 14 +#define AR_USEC_RX_LAT_M 0x1f800000 +#define AR_USEC_RX_LAT_S 23 +#define AR_USEC_ASYNC_FIFO_DUR 0x12e00074 + +/* Bits for AR_RESET_TSF. */ +#define AR_RESET_TSF_ONCE 0x01000000 + +/* Bits for AR_RX_FILTER. */ +#define AR_RX_FILTER_UCAST 0x00000001 +#define AR_RX_FILTER_MCAST 0x00000002 +#define AR_RX_FILTER_BCAST 0x00000004 +#define AR_RX_FILTER_CONTROL 0x00000008 +#define AR_RX_FILTER_BEACON 0x00000010 +#define AR_RX_FILTER_PROM 0x00000020 +#define AR_RX_FILTER_PROBEREQ 0x00000080 +#define AR_RX_FILTER_MYBEACON 0x00000200 +#define AR_RX_FILTER_COMPR_BAR 0x00000400 +#define AR_RX_FILTER_PSPOLL 0x00004000 + +/* Bits for AR_DIAG_SW. */ +#define AR_DIAG_CACHE_ACK 0x00000001 +#define AR_DIAG_ACK_DIS 0x00000002 +#define AR_DIAG_CTS_DIS 0x00000004 +#define AR_DIAG_ENCRYPT_DIS 0x00000008 +#define AR_DIAG_DECRYPT_DIS 0x00000010 +#define AR_DIAG_RX_DIS 0x00000020 +#define AR_DIAG_LOOP_BACK 0x00000040 +#define AR_DIAG_CORR_FCS 0x00000080 +#define AR_DIAG_CHAN_INFO 0x00000100 +#define AR_DIAG_SCRAM_SEED_M 0x0001fe00 +#define AR_DIAG_SCRAM_SEED_S 8 /* XXX should be 9? */ +#define AR_DIAG_FRAME_NV0 0x00020000 +#define AR_DIAG_OBS_PT_SEL1_M 0x000c0000 +#define AR_DIAG_OBS_PT_SEL1_S 18 +#define AR_DIAG_FORCE_RX_CLEAR 0x00100000 +#define AR_DIAG_IGNORE_VIRT_CS 0x00200000 +#define AR_DIAG_FORCE_CH_IDLE_HIGH 0x00400000 +#define AR_DIAG_EIFS_CTRL_ENA 0x00800000 +#define AR_DIAG_DUAL_CHAIN_INFO 0x01000000 +#define AR_DIAG_RX_ABORT 0x02000000 +#define AR_DIAG_SATURATE_CYCLE_CNT 0x04000000 +#define AR_DIAG_OBS_PT_SEL2 0x08000000 +#define AR_DIAG_RX_CLEAR_CTL_LOW 0x10000000 +#define AR_DIAG_RX_CLEAR_EXT_LOW 0x20000000 + +/* Bits for AR_AES_MUTE_MASK0. */ +#define AR_AES_MUTE_MASK0_FC_M 0x0000ffff +#define AR_AES_MUTE_MASK0_FC_S 0 +#define AR_AES_MUTE_MASK0_QOS_M 0xffff0000 +#define AR_AES_MUTE_MASK0_QOS_S 16 + +/* Bits for AR_AES_MUTE_MASK1. */ +#define AR_AES_MUTE_MASK1_SEQ_M 0x0000ffff +#define AR_AES_MUTE_MASK1_SEQ_S 0 +#define AR_AES_MUTE_MASK1_FC_MGMT_M 0xffff0000 +#define AR_AES_MUTE_MASK1_FC_MGMT_S 16 +#define AR_AES_MUTE_MASK1_FC0_MGMT_M 0x00ff0000 +#define AR_AES_MUTE_MASK1_FC0_MGMT_S 16 +#define AR_AES_MUTE_MASK1_FC1_MGMT_M 0xff000000 +#define AR_AES_MUTE_MASK1_FC1_MGMT_S 24 + +/* Bits for AR_GATED_CLKS. */ +#define AR_GATED_CLKS_TX 0x00000002 +#define AR_GATED_CLKS_RX 0x00000004 +#define AR_GATED_CLKS_REG 0x00000008 + +/* Bits for AR_OBS_BUS_CTRL. */ +#define AR_OBS_BUS_SEL_1 0x00040000 +#define AR_OBS_BUS_SEL_2 0x00080000 +#define AR_OBS_BUS_SEL_3 0x000c0000 +#define AR_OBS_BUS_SEL_4 0x08040000 +#define AR_OBS_BUS_SEL_5 0x08080000 + +/* Bits for AR_OBS_BUS_1. */ +#define AR_OBS_BUS_1_PCU 0x00000001 +#define AR_OBS_BUS_1_RX_END 0x00000002 +#define AR_OBS_BUS_1_RX_WEP 0x00000004 +#define AR_OBS_BUS_1_RX_BEACON 0x00000008 +#define AR_OBS_BUS_1_RX_FILTER 0x00000010 +#define AR_OBS_BUS_1_TX_HCF 0x00000020 +#define AR_OBS_BUS_1_QUIET_TIME 0x00000040 +#define AR_OBS_BUS_1_CHAN_IDLE 0x00000080 +#define AR_OBS_BUS_1_TX_HOLD 0x00000100 +#define AR_OBS_BUS_1_TX_FRAME 0x00000200 +#define AR_OBS_BUS_1_RX_FRAME 0x00000400 +#define AR_OBS_BUS_1_RX_CLEAR 0x00000800 +#define AR_OBS_BUS_1_WEP_STATE_M 0x0003f000 +#define AR_OBS_BUS_1_WEP_STATE_S 12 +#define AR_OBS_BUS_1_RX_STATE_M 0x01f00000 +#define AR_OBS_BUS_1_RX_STATE_S 20 +#define AR_OBS_BUS_1_TX_STATE_M 0x7e000000 +#define AR_OBS_BUS_1_TX_STATE_S 25 + +/* Bits for AR_SLEEP1. */ +#define AR_SLEEP1_ASSUME_DTIM 0x00080000 +#define AR_SLEEP1_CAB_TIMEOUT_M 0xffe00000 +#define AR_SLEEP1_CAB_TIMEOUT_S 21 +/* Default value. */ +#define AR_CAB_TIMEOUT_VAL 10 + +/* Bits for AR_SLEEP2. */ +#define AR_SLEEP2_BEACON_TIMEOUT_M 0xffe00000 +#define AR_SLEEP2_BEACON_TIMEOUT_S 21 + +/* Bits for AR_TPC. */ +#define AR_TPC_ACK_M 0x0000003f +#define AR_TPC_ACK_S 0 +#define AR_TPC_CTS_M 0x00003f00 +#define AR_TPC_CTS_S 8 +#define AR_TPC_CHIRP_M 0x003f0000 +#define AR_TPC_CHIRP_S 16 + +/* Bits for AR_QUIET1. */ +#define AR_QUIET1_NEXT_QUIET_M 0x0000ffff +#define AR_QUIET1_NEXT_QUIET_S 0 +#define AR_QUIET1_QUIET_ENABLE 0x00010000 +#define AR_QUIET1_QUIET_ACK_CTS_ENABLE 0x00020000 + +/* Bits for AR_QUIET2. */ +#define AR_QUIET2_QUIET_PERIOD_M 0x0000ffff +#define AR_QUIET2_QUIET_PERIOD_S 0 +#define AR_QUIET2_QUIET_DUR_M 0xffff0000 +#define AR_QUIET2_QUIET_DUR_S 16 + +/* Bits for AR_TSF_PARM. */ +#define AR_TSF_INCREMENT_M 0x000000ff +#define AR_TSF_INCREMENT_S 0 + +/* Bits for AR_QOS_NO_ACK. */ +#define AR_QOS_NO_ACK_TWO_BIT_M 0x0000000f +#define AR_QOS_NO_ACK_TWO_BIT_S 0 +#define AR_QOS_NO_ACK_BIT_OFF_M 0x0000007f +#define AR_QOS_NO_ACK_BIT_OFF_S 4 +#define AR_QOS_NO_ACK_BYTE_OFF_M 0x00000180 +#define AR_QOS_NO_ACK_BYTE_OFF_S 7 + +/* Bits for AR_PHY_ERR. */ +#define AR_PHY_ERR_DCHIRP 0x00000008 +#define AR_PHY_ERR_RADAR 0x00000020 +#define AR_PHY_ERR_OFDM_TIMING 0x00020000 +#define AR_PHY_ERR_CCK_TIMING 0x02000000 + +/* Bits for AR_PCU_MISC. */ +#define AR_PCU_FORCE_BSSID_MATCH 0x00000001 +#define AR_PCU_MIC_NEW_LOC_ENA 0x00000004 +#define AR_PCU_TX_ADD_TSF 0x00000008 +#define AR_PCU_CCK_SIFS_MODE 0x00000010 +#define AR_PCU_RX_ANT_UPDT 0x00000800 +#define AR_PCU_TXOP_TBTT_LIMIT_ENA 0x00001000 +#define AR_PCU_MISS_BCN_IN_SLEEP 0x00004000 +#define AR_PCU_BUG_12306_FIX_ENA 0x00020000 +#define AR_PCU_FORCE_QUIET_COLL 0x00040000 +#define AR_PCU_BT_ANT_PREVENT_RX 0x00100000 +#define AR_PCU_TBTT_PROTECT 0x00200000 +#define AR_PCU_CLEAR_VMF 0x01000000 +#define AR_PCU_CLEAR_BA_VALID 0x04000000 + +/* Bits for AR_BT_COEX_MODE. */ +#define AR_BT_TIME_EXTEND_M 0x000000ff +#define AR_BT_TIME_EXTEND_S 0 +#define AR_BT_TXSTATE_EXTEND 0x00000100 +#define AR_BT_TX_FRAME_EXTEND 0x00000200 +#define AR_BT_MODE_M 0x00000c00 +#define AR_BT_MODE_S 10 +#define AR_BT_MODE_LEGACY 0 +#define AR_BT_MODE_UNSLOTTED 1 +#define AR_BT_MODE_SLOTTED 2 +#define AR_BT_MODE_DISABLED 3 +#define AR_BT_QUIET 0x00001000 +#define AR_BT_QCU_THRESH_M 0x0001e000 +#define AR_BT_QCU_THRESH_S 13 +#define AR_BT_RX_CLEAR_POLARITY 0x00020000 +#define AR_BT_PRIORITY_TIME_M 0x00fc0000 +#define AR_BT_PRIORITY_TIME_S 18 +#define AR_BT_FIRST_SLOT_TIME_M 0xff000000 +#define AR_BT_FIRST_SLOT_TIME_S 24 + +/* Bits for AR_BT_COEX_WEIGHT. */ +#define AR_BTCOEX_BT_WGHT_M 0x0000ffff +#define AR_BTCOEX_BT_WGHT_S 0 +#define AR_STOMP_LOW_BT_WGHT 0xff55 +#define AR_BTCOEX_WL_WGHT_M 0xffff0000 +#define AR_BTCOEX_WL_WGHT_S 16 +#define AR_STOMP_LOW_WL_WGHT 0xaaa8 + +/* Bits for AR_BT_COEX_MODE2. */ +#define AR_BT_BCN_MISS_THRESH_M 0x000000ff +#define AR_BT_BCN_MISS_THRESH_S 0 +#define AR_BT_BCN_MISS_CNT_M 0x0000ff00 +#define AR_BT_BCN_MISS_CNT_S 8 +#define AR_BT_HOLD_RX_CLEAR 0x00010000 +#define AR_BT_DISABLE_BT_ANT 0x00100000 + +/* Bits for AR_PCU_BA_BAR_CTRL. */ +#define AR_PCU_BA_BAR_COMRESSED 0x00000100 +#define AR_PCU_BA_BAR_ACK_POLICY 0x00000200 +#define AR_PCU_BA_BAR_ACK_POLICY_OFFSET_M 0x000000f0 +#define AR_PCU_BA_BAR_ACK_POLICY_OFFSET_S 4 +#define AR_PCU_BA_BAR_COMPRESSED_OFFSET_M 0x0000000f +#define AR_PCU_BA_BAR_COMPRESSED_OFFSET_S 0 + +/* Bits for AR_PCU_TXBUF_CTRL. */ +#define AR_PCU_TXBUF_CTRL_SIZE_M 0x000007ff +#define AR_PCU_TXBUF_CTRL_SIZE_S 0 +#define AR_PCU_TXBUF_CTRL_USABLE_SIZE 1792 +#define AR9285_PCU_TXBUF_CTRL_USABLE_SIZE (1792 / 2) + +/* Bits for AR_PCU_MISC_MODE2. */ +#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE 0x00000002 +#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT 0x00000004 +#define AR_PCU_MISC_MODE2_AGG_WEP_ENABLE_FIX 0x00000008 +#define AR_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE 0x00000040 +#define AR_PCU_MISC_MODE2_CFP_IGNORE 0x00000080 +#define AR_PCU_MISC_MODE2_MGMT_QOS_M 0x0000ff00 +#define AR_PCU_MISC_MODE2_MGMT_QOS_S 8 +#define AR_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DUR 0x00010000 +#define AR_PCU_MISC_MODE2_ENABLE_AGGWEP 0x00020000 +#define AR_PCU_MISC_MODE2_HWWAR1 0x00100000 +#define AR_PCU_MISC_MODE2_HWWAR2 0x02000000 + +/* Bits for AR_MAC_PCU_LOGIC_ANALYZER. */ +#define AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768 0x20000000 + +/* Bits for AR_MAC_PCU_ASYNC_FIFO_REG3. */ +#define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL 0x00000400 +#define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET 0x80000000 + +/* Bits for AR_PHY_ERR_[123]. */ +#define AR_PHY_ERR_COUNT_M 0x00ffffff +#define AR_PHY_ERR_COUNT_S 0 + +/* Bits for AR_TSFOOR_THRESHOLD. */ +#define AR_TSFOOR_THRESHOLD_VAL_M 0x0000ffff +#define AR_TSFOOR_THRESHOLD_VAL_S 0 + +/* Bit for AR_TXSIFS. */ +#define AR_TXSIFS_TIME_M 0x000000ff +#define AR_TXSIFS_TIME_S 0 +#define AR_TXSIFS_TX_LATENCY_M 0x00000f00 +#define AR_TXSIFS_TX_LATENCY_S 8 +#define AR_TXSIFS_ACK_SHIFT_M 0x00007000 +#define AR_TXSIFS_ACK_SHIFT_S 12 + +/* Bits for AR_TXOP_X. */ +#define AR_TXOP_X_VAL 0x000000ff + +/* Bits for AR_TIMER_MODE. */ +#define AR_TBTT_TIMER_EN 0x00000001 +#define AR_DBA_TIMER_EN 0x00000002 +#define AR_SWBA_TIMER_EN 0x00000004 +#define AR_HCF_TIMER_EN 0x00000008 +#define AR_TIM_TIMER_EN 0x00000010 +#define AR_DTIM_TIMER_EN 0x00000020 +#define AR_QUIET_TIMER_EN 0x00000040 +#define AR_NDP_TIMER_EN 0x00000080 +#define AR_TIMER_OVERFLOW_INDEX_M 0x00000700 +#define AR_TIMER_OVERFLOW_INDEX_S 8 +#define AR_TIMER_THRESH_M 0xfffff000 +#define AR_TIMER_THRESH_S 12 + +/* Bits for AR_SLP32_MODE. */ +#define AR_SLP32_HALF_CLK_LATENCY_M 0x000fffff +#define AR_SLP32_HALF_CLK_LATENCY_S 0 +#define AR_SLP32_ENA 0x00100000 +#define AR_SLP32_TSF_WRITE_STATUS 0x00200000 + +/* Bits for AR_SLP32_WAKE. */ +#define AR_SLP32_WAKE_XTL_TIME_M 0x0000ffff +#define AR_SLP32_WAKE_XTL_TIME_S 0 + +/* Bits for AR_SLP_MIB_CTRL. */ +#define AR_SLP_MIB_CLEAR 0x00000001 +#define AR_SLP_MIB_PENDING 0x00000002 + +/* Bits for AR_2040_MODE. */ +#define AR_2040_JOINED_RX_CLEAR 0x00000001 + +/* Bits for AR_KEYTABLE_TYPE. */ +#define AR_KEYTABLE_TYPE_M 0x00000007 +#define AR_KEYTABLE_TYPE_S 0 +#define AR_KEYTABLE_TYPE_40 0 +#define AR_KEYTABLE_TYPE_104 1 +#define AR_KEYTABLE_TYPE_128 3 +#define AR_KEYTABLE_TYPE_TKIP 4 +#define AR_KEYTABLE_TYPE_AES 5 +#define AR_KEYTABLE_TYPE_CCM 6 +#define AR_KEYTABLE_TYPE_CLR 7 +#define AR_KEYTABLE_ANT 0x00000008 +#define AR_KEYTABLE_VALID 0x00008000 + +/* + * AR9271 specific registers. + */ +#define AR9271_CLOCK_CONTROL 0x050040 +#define AR9271_RESET_POWER_DOWN_CONTROL 0x050044 +#define AR9271_FIRMWARE 0x501000 +#define AR9271_FIRMWARE_TEXT 0x903000 +#define AR7010_FIRMWARE_TEXT 0x906000 + +/* Bits for AR9271_RESET_POWER_DOWN_CONTROL. */ +#define AR9271_RADIO_RF_RST 0x00000020 +#define AR9271_GATE_MAC_CTL 0x00004000 + + +#define AR_BASE_PHY_ACTIVE_DELAY 100 + +#define AR_CLOCK_RATE_CCK 22 +#define AR_CLOCK_RATE_5GHZ_OFDM 40 +#define AR_CLOCK_RATE_FAST_5GHZ_OFDM 44 +#define AR_CLOCK_RATE_2GHZ_OFDM 44 + +#define AR_PWR_DECREASE_FOR_2_CHAIN 6 /* 10 * log10(2) * 2 */ +#define AR_PWR_DECREASE_FOR_3_CHAIN 9 /* 10 * log10(3) * 2 */ + +#define AR_SLEEP_SLOP 3 /* TUs */ + +#define AR_MIN_BEACON_TIMEOUT_VAL 1 +#define AR_FUDGE 2 +#define AR_BEACON_DMA_DELAY 2 +#define AR_SWBA_DELAY 10 +/* Divides by 1024 (usecs to TU) without doing 64-bit arithmetic. */ +#define AR_TSF_TO_TU(hi, lo) ((hi) << 22 | (lo) >> 10) + +#define AR_KEY_CACHE_SIZE 128 +#define AR_RSVD_KEYTABLE_ENTRIES 4 + +#define AR_CAL_SAMPLES 64 /* XXX AR9280? */ +#define AR_MAX_LOG_CAL 2 /* XXX AR9280? */ + +/* Maximum number of chains supported by any chipset. */ +#define AR_MAX_CHAINS 3 + +/* Default number of key cache entries. */ +#define AR_KEYTABLE_SIZE 128 + +/* GPIO pins. */ +#define AR_GPIO_WLANACTIVE_PIN 5 +#define AR_GPIO_BTACTIVE_PIN 6 +#define AR_GPIO_BTPRIORITY_PIN 7 + +#define AR_SREV_5416(sc) \ + ((sc)->mac_ver == AR_SREV_VERSION_5416_PCI || \ + (sc)->mac_ver == AR_SREV_VERSION_5416_PCIE) +#define AR_SREV_5416_20_OR_LATER(sc) \ + ((AR_SREV_5416(sc) && \ + (sc)->mac_rev >= AR_SREV_REVISION_5416_20) || \ + (sc)->mac_ver >= AR_SREV_VERSION_9100) +#define AR_SREV_5416_22_OR_LATER(sc) \ + ((AR_SREV_5416(sc) && \ + (sc)->mac_rev >= AR_SREV_REVISION_5416_22) || \ + (sc)->mac_ver >= AR_SREV_VERSION_9100) + +#define AR_SREV_9160(sc) \ + ((sc)->mac_ver == AR_SREV_VERSION_9160) +#define AR_SREV_9160_10_OR_LATER(sc) \ + ((sc)->mac_ver >= AR_SREV_VERSION_9160) +#define AR_SREV_9160_11(sc) \ + (AR_SREV_9160(sc) && \ + (sc)->mac_rev == AR_SREV_REVISION_9160_11) + +#define AR_SREV_9280(sc) \ + ((sc)->mac_ver == AR_SREV_VERSION_9280) +#define AR_SREV_9280_10_OR_LATER(sc) \ + ((sc)->mac_ver >= AR_SREV_VERSION_9280) +#define AR_SREV_9280_10(sc) \ + (AR_SREV_9280(sc) && \ + (sc)->mac_rev == AR_SREV_REVISION_9280_10) +#define AR_SREV_9280_20(sc) \ + (AR_SREV_9280(sc) && \ + (sc)->mac_rev >= AR_SREV_REVISION_9280_20) +#define AR_SREV_9280_20_OR_LATER(sc) \ + ((sc)->mac_ver > AR_SREV_VERSION_9280 || \ + (AR_SREV_9280(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9280_20)) + +#define AR_SREV_9285(sc) \ + ((sc)->mac_ver == AR_SREV_VERSION_9285) +#define AR_SREV_9285_10_OR_LATER(sc) \ + ((sc)->mac_ver >= AR_SREV_VERSION_9285) +#define AR_SREV_9285_11(sc) \ + (AR_SREV_9285(sc) && \ + (sc)->mac_rev == AR_SREV_REVISION_9285_11) +#define AR_SREV_9285_11_OR_LATER(sc) \ + ((sc)->mac_ver > AR_SREV_VERSION_9285 || \ + (AR_SREV_9285(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9285_11)) +#define AR_SREV_9285_12(sc) \ + (AR_SREV_9285(sc) && \ + ((sc)->mac_rev == AR_SREV_REVISION_9285_12)) +#define AR_SREV_9285_12_OR_LATER(sc) \ + ((sc)->mac_ver > AR_SREV_VERSION_9285 || \ + (AR_SREV_9285(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9285_12)) + +#define AR_SREV_9271(sc) \ + ((sc)->mac_ver == AR_SREV_VERSION_9271) +#define AR_SREV_9271_10(sc) \ + (AR_SREV_9271(sc) && \ + (sc)->mac_rev == AR_SREV_REVISION_9271_10) + +#define AR_SREV_9287(sc) \ + ((sc)->mac_ver == AR_SREV_VERSION_9287) +#define AR_SREV_9287_10_OR_LATER(sc) \ + ((sc)->mac_ver >= AR_SREV_VERSION_9287) +#define AR_SREV_9287_10(sc) \ + ((sc)->mac_ver == AR_SREV_VERSION_9287 && \ + (sc)->mac_rev == AR_SREV_REVISION_9287_10) +#define AR_SREV_9287_11(sc) \ + ((sc)->mac_ver == AR_SREV_VERSION_9287 && \ + (sc)->mac_rev == AR_SREV_REVISION_9287_11) +#define AR_SREV_9287_11_OR_LATER(sc) \ + ((sc)->mac_ver > AR_SREV_VERSION_9287 || \ + (AR_SREV_9287(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9287_11)) +#define AR_SREV_9287_12(sc) \ + ((sc)->mac_ver == AR_SREV_VERSION_9287 && \ + (sc)->mac_rev == AR_SREV_REVISION_9287_12) +#define AR_SREV_9287_12_OR_LATER(sc) \ + ((sc)->mac_ver > AR_SREV_VERSION_9287 || \ + (AR_SREV_9287(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9287_12)) +#define AR_SREV_9287_13_OR_LATER(sc) \ + ((sc)->mac_ver > AR_SREV_VERSION_9287 || \ + (AR_SREV_9287(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9287_13)) + +#define AR_SREV_9380(sc) \ + ((sc)->mac_ver == AR_SREV_VERSION_9380) +#define AR_SREV_9380_10_OR_LATER(sc) \ + ((sc)->mac_ver >= AR_SREV_VERSION_9380) +#define AR_SREV_9380_20(sc) \ + (AR_SREV_9380(sc) && \ + (sc)->mac_rev == AR_SREV_REVISION_9380_20) +#define AR_SREV_9380_20_OR_LATER(sc) \ + ((sc)->mac_ver > AR_SREV_VERSION_9380 || \ + (AR_SREV_9380(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9380_20)) + +#define AR_SREV_9485(sc) \ + ((sc)->mac_ver == AR_SREV_VERSION_9485) + +#define AR_SINGLE_CHIP(sc) AR_SREV_9280_10_OR_LATER(sc) + +#define AR_RADIO_SREV_MAJOR 0xf0 +#define AR_RAD5133_SREV_MAJOR 0xc0 +#define AR_RAD2133_SREV_MAJOR 0xd0 +#define AR_RAD5122_SREV_MAJOR 0xe0 +#define AR_RAD2122_SREV_MAJOR 0xf0 + +#define AR_BCHAN_UNUSED 0xff +#define AR_PD_GAINS_IN_MASK 4 /* NB: Max for all chips. */ +#define AR_MAX_RATE_POWER 63 + +#define AR_HT40_POWER_INC_FOR_PDADC 2 +#define AR_PWR_TABLE_OFFSET_DB (-5) +#define AR9280_TX_GAIN_TABLE_SIZE 22 +#define AR9003_TX_GAIN_TABLE_SIZE 32 +#define AR9003_PAPRD_MEM_TAB_SIZE 24 + +#define AR_BASE_FREQ_2GHZ 2300 +#define AR_BASE_FREQ_5GHZ 4900 + +#define AR_SD_NO_CTL 0xe0 +#define AR_NO_CTL 0xff +#define AR_CTL_MODE_M 0x07 +#define AR_CTL_MODE_S 0 +#define AR_CTL_11A 0 +#define AR_CTL_11B 1 +#define AR_CTL_11G 2 +#define AR_CTL_2GHT20 5 +#define AR_CTL_5GHT20 6 +#define AR_CTL_2GHT40 7 +#define AR_CTL_5GHT40 8 + +#define AR_DEFAULT_NOISE_FLOOR (-100) + +/* + * Macros to access registers. + */ +#define AR_READ(sc, reg) \ + (sc)->ops.read((sc), (reg)) + +#define AR_WRITE(sc, reg, val) \ + (sc)->ops.write((sc), (reg), (val)) + +#define AR_WRITE_BARRIER(sc) \ + (sc)->ops.write_barrier((sc)) + +#define AR_SETBITS(sc, reg, mask) \ + AR_WRITE(sc, reg, AR_READ(sc, reg) | (mask)) + +#define AR_CLRBITS(sc, reg, mask) \ + AR_WRITE(sc, reg, AR_READ(sc, reg) & ~(mask)) + +/* + * Macros to access subfields in registers. + */ +/* Mask and Shift (getter). */ +#define MS(val, field) \ + (((uint32_t)(val) & field##_M) >> field##_S) + +/* Shift and Mask (setter). */ +#define SM(field, val) \ + (((uint32_t)(val) << field##_S) & field##_M) + +/* Rewrite. */ +#define RW(var, field, val) \ + (((var) & ~field##_M) | SM(field, val)) diff --git a/sys/dev/athn/headers/athnvar.h b/sys/dev/athn/headers/athnvar.h new file mode 100644 --- /dev/null +++ b/sys/dev/athn/headers/athnvar.h @@ -0,0 +1,750 @@ +/* $OpenBSD: athnvar.h,v 1.42 2021/04/15 18:25:43 stsp Exp $ */ + +/*- + * Copyright (c) 2009 Damien Bergamini + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef IF_ATHNVAR_H +#define IF_ATHNVAR_H + +//#include +#include +#include +#include "../../../../crypto/openssh/openbsd-compat/sys-queue.h" +#include "openbsd_adapt.h" +//#include + +#include +#include +#include + +#include +#include +#include +#include +#include "ar5008reg.h" +#define NBPFILTER 0 + +#ifdef notyet +#define ATHN_BT_COEXISTENCE 1 +#endif + +#ifdef ATHN_DEBUG +#define DPRINTF(x) do { if (athn_debug > 0) printf x; } while (0) +#define DPRINTFN(n, x) do { if (athn_debug >= (n)) printf x; } while (0) +extern int athn_debug; +#else +#define DPRINTF(x) +#define DPRINTFN(n, x) +#endif + +#define LE_READ_4(p) ((p)[0] | (p)[1] << 8 | (p)[2] << 16 | (p)[3] << 24) +#define LE_READ_2(p) ((p)[0] | (p)[1] << 8) + +#define ATHN_RXBUFSZ 3872 +#define ATHN_TXBUFSZ 4096 + +#define ATHN_NRXBUFS 64 +#define ATHN_NTXBUFS 64 /* Shared between all Tx queues. */ + +// TODO missing in linux/ieee80211.h +#define EDCA_NUM_AC 4 + +struct athn_rx_radiotap_header { + struct ieee80211_radiotap_header wr_ihdr; + uint64_t wr_tsft; + uint8_t wr_flags; + uint8_t wr_rate; + uint16_t wr_chan_freq; + uint16_t wr_chan_flags; + int8_t wr_dbm_antsignal; + uint8_t wr_antenna; +} __packed; + +#define ATHN_RX_RADIOTAP_PRESENT \ + (1 << IEEE80211_RADIOTAP_TSFT | \ + 1 << IEEE80211_RADIOTAP_FLAGS | \ + 1 << IEEE80211_RADIOTAP_RATE | \ + 1 << IEEE80211_RADIOTAP_CHANNEL | \ + 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL | \ + 1 << IEEE80211_RADIOTAP_ANTENNA) + +struct athn_tx_radiotap_header { + struct ieee80211_radiotap_header wt_ihdr; + uint8_t wt_flags; + uint8_t wt_rate; + uint16_t wt_chan_freq; + uint16_t wt_chan_flags; +} __packed; + +#define ATHN_TX_RADIOTAP_PRESENT \ + (1 << IEEE80211_RADIOTAP_FLAGS | \ + 1 << IEEE80211_RADIOTAP_RATE | \ + 1 << IEEE80211_RADIOTAP_CHANNEL) + +struct athn_tx_buf { + SIMPLEQ_ENTRY(athn_tx_buf) bf_list; + + void *bf_descs; + bus_dmamap_t bf_map; + bus_addr_t bf_daddr; + + struct mbuf *bf_m; + struct ieee80211_node *bf_ni; + int bf_txmcs; + int bf_txflags; +#define ATHN_TXFLAG_PAPRD (1 << 0) +#define ATHN_TXFLAG_CAB (1 << 1) +}; + +struct athn_txq { + SIMPLEQ_HEAD(, athn_tx_buf) head; + void *lastds; + struct athn_tx_buf *wait; + int queued; +}; + +struct athn_rx_buf { + SIMPLEQ_ENTRY(athn_rx_buf) bf_list; + + void *bf_desc; + bus_dmamap_t bf_map; + + struct mbuf *bf_m; + bus_addr_t bf_daddr; +}; + +struct athn_rxq { + struct athn_rx_buf *bf; + + void *descs; + void *lastds; + bus_dmamap_t map; + bus_dma_segment_t seg; + int count; + + SIMPLEQ_HEAD(, athn_rx_buf) head; +}; + +/* Software rate indexes. */ +#define ATHN_RIDX_CCK1 0 +#define ATHN_RIDX_CCK2 1 +#define ATHN_RIDX_OFDM6 4 +#define ATHN_RIDX_MCS0 12 +#define ATHN_RIDX_MCS8 (ATHN_RIDX_MCS0 + 8) +#define ATHN_RIDX_MCS15 27 +#define ATHN_RIDX_MAX 27 +#define ATHN_MCS_MAX 15 +#define ATHN_NUM_MCS (ATHN_MCS_MAX + 1) +#define ATHN_IS_HT_RIDX(ridx) ((ridx) >= ATHN_RIDX_MCS0) +#define ATHN_IS_MIMO_RIDX(ridx) ((ridx) >= ATHN_RIDX_MCS8) + +static const struct athn_rate { + uint16_t rate; /* Rate in 500Kbps unit. */ + uint8_t hwrate; /* HW representation. */ + uint8_t rspridx; /* Control Response Frame rate index. */ + enum ieee80211_phytype phy; +} athn_rates[] = { + { 2, 0x1b, 0, IEEE80211_T_DS }, + { 4, 0x1a, 1, IEEE80211_T_DS }, + { 11, 0x19, 1, IEEE80211_T_DS }, + { 22, 0x18, 1, IEEE80211_T_DS }, + { 12, 0x0b, 4, IEEE80211_T_OFDM }, + { 18, 0x0f, 4, IEEE80211_T_OFDM }, + { 24, 0x0a, 6, IEEE80211_T_OFDM }, + { 36, 0x0e, 6, IEEE80211_T_OFDM }, + { 48, 0x09, 8, IEEE80211_T_OFDM }, + { 72, 0x0d, 8, IEEE80211_T_OFDM }, + { 96, 0x08, 8, IEEE80211_T_OFDM }, + { 108, 0x0c, 8, IEEE80211_T_OFDM }, + { 13, 0x80, 4, IEEE80211_T_OFDM }, + { 26, 0x81, 6, IEEE80211_T_OFDM }, + { 39, 0x82, 6, IEEE80211_T_OFDM }, + { 52, 0x83, 8, IEEE80211_T_OFDM }, + { 78, 0x84, 8, IEEE80211_T_OFDM }, + { 104, 0x85, 8, IEEE80211_T_OFDM }, + { 117, 0x86, 8, IEEE80211_T_OFDM }, + { 130, 0x87, 8, IEEE80211_T_OFDM }, + { 26, 0x88, 4, IEEE80211_T_OFDM }, + { 52, 0x89, 6, IEEE80211_T_OFDM }, + { 78, 0x8a, 8, IEEE80211_T_OFDM }, + { 104, 0x8b, 8, IEEE80211_T_OFDM }, + { 156, 0x8c, 8, IEEE80211_T_OFDM }, + { 208, 0x8d, 8, IEEE80211_T_OFDM }, + { 234, 0x8e, 8, IEEE80211_T_OFDM }, + { 260, 0x8f, 8, IEEE80211_T_OFDM } +}; + +struct athn_series { + uint16_t dur; + uint8_t hwrate; +}; + +struct athn_pier { + uint8_t fbin; + const uint8_t *pwr[AR_PD_GAINS_IN_MASK]; + const uint8_t *vpd[AR_PD_GAINS_IN_MASK]; +}; + +/* + * Structures used to store initialization values. + */ +struct athn_ini { + int nregs; + const uint16_t *regs; + const uint32_t *vals_5g20; + const uint32_t *vals_5g40; + const uint32_t *vals_2g40; + const uint32_t *vals_2g20; + int ncmregs; + const uint16_t *cmregs; + const uint32_t *cmvals; + int nfastregs; + const uint16_t *fastregs; + const uint32_t *fastvals_5g20; + const uint32_t *fastvals_5g40; +}; + +struct athn_gain { + int nregs; + const uint16_t *regs; + const uint32_t *vals_5g; + const uint32_t *vals_2g; +}; + +struct athn_addac { + int nvals; + const uint32_t *vals; +}; + +struct athn_serdes { + int nvals; + const uint32_t *regs; + const uint32_t *vals; +}; + +/* Rx queue software indexes. */ +#define ATHN_QID_LP 0 +#define ATHN_QID_HP 1 + +/* Tx queue software indexes. */ +#define ATHN_QID_AC_BE 0 +#define ATHN_QID_PSPOLL 1 +#define ATHN_QID_AC_BK 2 +#define ATHN_QID_AC_VI 3 +#define ATHN_QID_AC_VO 4 +#define ATHN_QID_UAPSD 5 +#define ATHN_QID_CAB 6 +#define ATHN_QID_BEACON 7 +#define ATHN_QID_COUNT 8 + +/* Map Access Category to Tx queue Id. */ +static const uint8_t athn_ac2qid[WME_NUM_AC] = { + ATHN_QID_AC_BE, /* WME_AC_BE */ + ATHN_QID_AC_BK, /* WME_AC_BK */ + ATHN_QID_AC_VI, /* WME_AC_VI */ + ATHN_QID_AC_VO /* WME_AC_VO */ +}; + +static const uint8_t athn_2ghz_chans[] = { + 1, 2, 3, 4, 5, 6 , 7, 8, 9, 10, 11, 12, 13, 14 +}; + +static const uint8_t athn_5ghz_chans[] = { + /* UNII 1. */ + 36, 40, 44, 48, + /* UNII 2. */ + 52, 56, 60, 64, + /* Middle band. */ + 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, + /* UNII 3. */ + 149, 153, 157, 161, 165 +}; + +/* Number of data bits per OFDM symbol for MCS[0-15]. */ +/* See tables 20-29, 20-30, 20-33, 20-34. */ +static const uint16_t ar_mcs_ndbps[][2] = { + /* 20MHz 40MHz */ + { 26, 54 }, /* MCS0 */ + { 52, 108 }, /* MCS1 */ + { 78, 162 }, /* MCS2 */ + { 104, 216 }, /* MCS3 */ + { 156, 324 }, /* MCS4 */ + { 208, 432 }, /* MCS5 */ + { 234, 486 }, /* MCS6 */ + { 260, 540 }, /* MCS7 */ + { 26, 108 }, /* MCS8 */ + { 52, 216 }, /* MCS9 */ + { 78, 324 }, /* MCS10 */ + { 104, 432 }, /* MCS11 */ + { 156, 648 }, /* MCS12 */ + { 208, 864 }, /* MCS13 */ + { 234, 972 }, /* MCS14 */ + { 260, 1080 } /* MCS15 */ +}; + +#define ATHN_POWER_OFDM6 0 +#define ATHN_POWER_OFDM9 1 +#define ATHN_POWER_OFDM12 2 +#define ATHN_POWER_OFDM18 3 +#define ATHN_POWER_OFDM24 4 +#define ATHN_POWER_OFDM36 5 +#define ATHN_POWER_OFDM48 6 +#define ATHN_POWER_OFDM54 7 +#define ATHN_POWER_CCK1_LP 8 +#define ATHN_POWER_CCK2_LP 9 +#define ATHN_POWER_CCK2_SP 10 +#define ATHN_POWER_CCK55_LP 11 +#define ATHN_POWER_CCK55_SP 12 +#define ATHN_POWER_CCK11_LP 13 +#define ATHN_POWER_CCK11_SP 14 +#define ATHN_POWER_XR 15 +#define ATHN_POWER_HT20(mcs) (16 + (mcs)) +#define ATHN_POWER_HT40(mcs) (40 + (mcs)) +#define ATHN_POWER_CCK_DUP 64 +#define ATHN_POWER_OFDM_DUP 65 +#define ATHN_POWER_CCK_EXT 66 +#define ATHN_POWER_OFDM_EXT 67 +#define ATHN_POWER_COUNT 68 + +#define ATHN_NUM_LEGACY_RATES IEEE80211_RATE_MAXSIZE +#define ATHN_NUM_RATES (ATHN_NUM_LEGACY_RATES + ATHN_NUM_MCS) +struct athn_node { + struct ieee80211_node ni; + struct ieee80211_amrr_node amn; +// struct ieee80211_ra_node rn; + uint8_t ridx[ATHN_NUM_RATES]; + uint8_t fallback[ATHN_NUM_RATES]; + uint8_t sta_index; +}; + +/* + * Adaptive noise immunity state. + */ +#define ATHN_ANI_PERIOD 100 +#define ATHN_ANI_RSSI_THR_HIGH 40 +#define ATHN_ANI_RSSI_THR_LOW 7 +struct athn_ani { + uint8_t noise_immunity_level; + uint8_t spur_immunity_level; + uint8_t firstep_level; + uint8_t ofdm_weak_signal; + uint8_t cck_weak_signal; + + uint32_t listen_time; + + uint32_t ofdm_trig_high; + uint32_t ofdm_trig_low; + + int32_t cck_trig_high; + int32_t cck_trig_low; + + uint32_t ofdm_phy_err_base; + uint32_t cck_phy_err_base; + uint32_t ofdm_phy_err_count; + uint32_t cck_phy_err_count; + + uint32_t cyccnt; + uint32_t txfcnt; + uint32_t rxfcnt; +}; + +struct athn_iq_cal { + uint32_t pwr_meas_i; + uint32_t pwr_meas_q; + int32_t iq_corr_meas; +}; + +struct athn_adc_cal { + uint32_t pwr_meas_odd_i; + uint32_t pwr_meas_even_i; + uint32_t pwr_meas_odd_q; + uint32_t pwr_meas_even_q; +}; + +struct athn_calib { + int nsamples; + struct athn_iq_cal iq[AR_MAX_CHAINS]; + struct athn_adc_cal adc_gain[AR_MAX_CHAINS]; + struct athn_adc_cal adc_dc_offset[AR_MAX_CHAINS]; +}; + +#define ATHN_NF_CAL_HIST_MAX 5 + +struct athn_softc; + +struct athn_vap { + struct ieee80211vap vap; + int (*newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +#define ATHN_VAP(vap) ((struct athn_vap *)(vap)) + +struct athn_ops { + /* Bus callbacks. */ + uint32_t (*read)(struct athn_softc *, uint32_t); + void (*write)(struct athn_softc *, uint32_t, uint32_t); + void (*write_barrier)(struct athn_softc *); + + void (*setup)(struct athn_softc *); + void (*set_txpower)(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); + void (*spur_mitigate)(struct athn_softc *, + struct ieee80211_channel *, struct ieee80211_channel *); + const struct ar_spur_chan * + (*get_spur_chans)(struct athn_softc *, int); + void (*init_from_rom)(struct athn_softc *, + struct ieee80211_channel *, struct ieee80211_channel *); + int (*set_synth)(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); + int (*read_rom_data)(struct athn_softc *, uint32_t, void *, int); + const uint8_t * + (*get_rom_template)(struct athn_softc *, uint8_t); + void (*swap_rom)(struct athn_softc *); + void (*olpc_init)(struct athn_softc *); + void (*olpc_temp_compensation)(struct athn_softc *); + /* GPIO callbacks. */ + int (*gpio_read)(struct athn_softc *, int); + void (*gpio_write)(struct athn_softc *, int, int); + void (*gpio_config_input)(struct athn_softc *, int); + void (*gpio_config_output)(struct athn_softc *, int, int); + void (*rfsilent_init)(struct athn_softc *); + /* DMA callbacks. */ + int (*dma_alloc)(struct athn_softc *); + void (*dma_free)(struct athn_softc *); + void (*rx_enable)(struct athn_softc *); + int (*intr)(struct athn_softc *); + int (*tx)(struct athn_softc *, struct mbuf *, + struct ieee80211_node *, int); + /* PHY callbacks. */ + void (*set_rf_mode)(struct athn_softc *, + struct ieee80211_channel *); + int (*rf_bus_request)(struct athn_softc *); + void (*rf_bus_release)(struct athn_softc *); + void (*set_phy)(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); + void (*set_delta_slope)(struct athn_softc *, + struct ieee80211_channel *, struct ieee80211_channel *); + void (*enable_antenna_diversity)(struct athn_softc *); + void (*init_baseband)(struct athn_softc *); + void (*disable_phy)(struct athn_softc *); + void (*set_rxchains)(struct athn_softc *); + void (*noisefloor_calib)(struct athn_softc *); + void (*init_noisefloor_calib)(struct athn_softc *); + int (*get_noisefloor)(struct athn_softc *); + void (*apply_noisefloor)(struct athn_softc *); + void (*do_calib)(struct athn_softc *); + void (*next_calib)(struct athn_softc *); + void (*hw_init)(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); + void (*get_paprd_masks)(struct athn_softc *sc, + struct ieee80211_channel *, uint32_t *, uint32_t *); + /* ANI callbacks. */ + void (*set_noise_immunity_level)(struct athn_softc *, int); + void (*enable_ofdm_weak_signal)(struct athn_softc *); + void (*disable_ofdm_weak_signal)(struct athn_softc *); + void (*set_cck_weak_signal)(struct athn_softc *, int); + void (*set_firstep_level)(struct athn_softc *, int); + void (*set_spur_immunity_level)(struct athn_softc *, int); +}; + + +/* + * ROM layout used by AR9285 (single-stream, 2GHz only). + */ +#ifndef AR9285_EEP_START_LOC +#define AR9285_EEP_START_LOC 64 +#define AR9285_NUM_2G_CAL_PIERS 3 +#define AR9285_NUM_2G_CCK_TARGET_POWERS 3 +#define AR9285_NUM_2G_20_TARGET_POWERS 3 +#define AR9285_NUM_2G_40_TARGET_POWERS 3 +#define AR9285_NUM_CTLS 12 +#define AR9285_NUM_BAND_EDGES 4 +#define AR9285_NUM_PD_GAINS 2 +#define AR9285_PD_GAINS_IN_MASK 4 +#define AR9285_PD_GAIN_ICEPTS 5 +#endif + +#ifndef AR_EEPROM_MODAL_SPURS + #define AR_EEPROM_MODAL_SPURS 5 +#endif + +struct ar9285_base_eep_header { + uint16_t length; + uint16_t checksum; + uint16_t version; + uint8_t opCapFlags; + uint8_t eepMisc; + uint16_t regDmn[2]; + uint8_t macAddr[6]; + uint8_t rxMask; + uint8_t txMask; + uint16_t rfSilent; + uint16_t blueToothOptions; + uint16_t deviceCap; + uint32_t binBuildNumber; + uint8_t deviceType; + /* End of common header. */ + uint8_t txGainType; +} __packed; + +struct ar9285_modal_eep_header { + uint32_t antCtrlChain; + uint32_t antCtrlCommon; + uint8_t antennaGain; + uint8_t switchSettling; + uint8_t txRxAtten; + uint8_t rxTxMargin; + uint8_t adcDesiredSize; + uint8_t pgaDesiredSize; + uint8_t xlnaGain; + uint8_t txEndToXpaOff; + uint8_t txEndToRxOn; + uint8_t txFrameToXpaOn; + uint8_t thresh62; + uint8_t noiseFloorThresh; + uint8_t xpdGain; + uint8_t xpd; + uint8_t iqCalI; + uint8_t iqCalQ; + uint8_t pdGainOverlap; + uint8_t ob_01; + uint8_t db1_01; + uint8_t xpaBiasLvl; + uint8_t txFrameToDataStart; + uint8_t txFrameToPaOn; + uint8_t ht40PowerIncForPdadc; + uint8_t bswAtten; + uint8_t bswMargin; + uint8_t swSettleHt40; + uint8_t xatten2Db; + uint8_t xatten2Margin; + uint8_t db2_01; + uint8_t version; + uint16_t ob_234; + uint16_t db1_234; + uint16_t db2_234; + uint8_t futureModal[4]; + struct ar_spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; +} __packed; + +struct ar9285_cal_data_per_freq { + uint8_t pwrPdg[AR9285_NUM_PD_GAINS][AR9285_PD_GAIN_ICEPTS]; + uint8_t vpdPdg[AR9285_NUM_PD_GAINS][AR9285_PD_GAIN_ICEPTS]; +} __packed; + +struct ar9285_cal_ctl_data { + struct ar_cal_ctl_edges ctlEdges[AR9285_NUM_BAND_EDGES]; +} __packed; + +struct ar9285_eeprom { + struct ar9285_base_eep_header baseEepHeader; + uint8_t custData[20]; + struct ar9285_modal_eep_header modalHeader; + uint8_t calFreqPier2G[AR9285_NUM_2G_CAL_PIERS]; + struct ar9285_cal_data_per_freq + calPierData2G[AR9285_NUM_2G_CAL_PIERS]; + struct ar_cal_target_power_leg + calTargetPowerCck[AR9285_NUM_2G_CCK_TARGET_POWERS]; + struct ar_cal_target_power_leg + calTargetPower2G[AR9285_NUM_2G_20_TARGET_POWERS]; + struct ar_cal_target_power_ht + calTargetPower2GHT20[AR9285_NUM_2G_20_TARGET_POWERS]; + struct ar_cal_target_power_ht + calTargetPower2GHT40[AR9285_NUM_2G_40_TARGET_POWERS]; + uint8_t ctlIndex[AR9285_NUM_CTLS]; + struct ar9285_cal_ctl_data ctlData[AR9285_NUM_CTLS]; + uint8_t padding; +} __packed; + +struct athn_softc { + struct athn_usb_softc *sc_usc; + device_t sc_dev; + struct ieee80211com sc_ic; + struct mbufq sc_snd; + + struct task sc_task; + struct timeout_task scan_to; + struct timeout_task calib_to; + + int (*sc_enable)(struct athn_softc *); + void (*sc_disable)(struct athn_softc *); + void (*sc_power)(struct athn_softc *, int); + void (*sc_disable_aspm)(struct athn_softc *); + void (*sc_enable_extsynch)( + struct athn_softc *); + + int (*sc_newstate)(struct ieee80211com *, + enum ieee80211_state, int); + + bus_dma_tag_t sc_dmat; + + struct ieee80211_amrr amrr; + + u_int flags; +#define ATHN_FLAG_PCIE (1 << 0) +#define ATHN_FLAG_USB (1 << 1) +#define ATHN_FLAG_OLPC (1 << 2) +#define ATHN_FLAG_PAPRD (1 << 3) +#define ATHN_FLAG_FAST_PLL_CLOCK (1 << 4) +#define ATHN_FLAG_RFSILENT (1 << 5) +#define ATHN_FLAG_RFSILENT_REVERSED (1 << 6) +#define ATHN_FLAG_BTCOEX2WIRE (1 << 7) +#define ATHN_FLAG_BTCOEX3WIRE (1 << 8) +/* Shortcut. */ +#define ATHN_FLAG_BTCOEX (ATHN_FLAG_BTCOEX2WIRE | ATHN_FLAG_BTCOEX3WIRE) +#define ATHN_FLAG_11A (1 << 9) +#define ATHN_FLAG_11G (1 << 10) +#define ATHN_FLAG_11N (1 << 11) +#define ATHN_FLAG_AN_TOP2_FIXUP (1 << 12) +#define ATHN_FLAG_NON_ENTERPRISE (1 << 13) +#define ATHN_FLAG_3TREDUCE_CHAIN (1 << 14) + + uint8_t ngpiopins; + int led_pin; + int rfsilent_pin; + int led_state; + uint32_t isync; + uint32_t imask; + + uint16_t mac_ver; + uint8_t mac_rev; + uint8_t rf_rev; + uint16_t eep_rev; + + uint8_t txchainmask; + uint8_t rxchainmask; + uint8_t ntxchains; + uint8_t nrxchains; + + uint8_t sup_calib_mask; + uint8_t cur_calib_mask; +#define ATHN_CAL_IQ (1 << 0) +#define ATHN_CAL_ADC_GAIN (1 << 1) +#define ATHN_CAL_ADC_DC (1 << 2) +#define ATHN_CAL_TEMP (1 << 3) + + struct ieee80211_channel *curchan; + struct ieee80211_channel *curchanext; + + /* Open Loop Power Control. */ + int8_t tx_gain_tbl[AR9280_TX_GAIN_TABLE_SIZE]; + int8_t pdadc; + int8_t tcomp; + int olpc_ticks; + int iqcal_ticks; + + /* PA predistortion. */ + uint16_t gain1[AR_MAX_CHAINS]; + uint32_t txgain[AR9003_TX_GAIN_TABLE_SIZE]; + int16_t pa_in[AR_MAX_CHAINS] + [AR9003_PAPRD_MEM_TAB_SIZE]; + int16_t angle[AR_MAX_CHAINS] + [AR9003_PAPRD_MEM_TAB_SIZE]; + int32_t trainpow; + uint8_t paprd_curchain; + + uint32_t rwbuf[64]; + + int kc_entries; + struct ar9285_eeprom eeprom; + // struct ar5416eeprom eeprom; + + void *eep; + const void *eep_def; + uint32_t eep_base; + uint32_t eep_size; + + struct athn_rxq rxq[2]; + struct athn_txq txq[31]; + + struct mtx sc_mtx; + + void *descs; + bus_dmamap_t map; + bus_dma_segment_t seg; + SIMPLEQ_HEAD(, athn_tx_buf) txbufs; + struct athn_tx_buf *bcnbuf; + struct athn_tx_buf txpool[ATHN_NTXBUFS]; + + bus_dmamap_t txsmap; + bus_dma_segment_t txsseg; + void *txsring; + int txscur; + + int sc_if_flags; + int sc_tx_timer; + + const struct athn_ini *ini; + const struct athn_gain *rx_gain; + const struct athn_gain *tx_gain; + const struct athn_addac *addac; + const struct athn_serdes *serdes; + uint32_t workaround; + uint32_t obs_off; + uint32_t gpio_input_en_off; + + struct athn_ops ops; + + int fixed_ridx; + + int16_t cca_min_2g; + int16_t cca_max_2g; + int16_t cca_min_5g; + int16_t cca_max_5g; + struct { + int16_t nf[AR_MAX_CHAINS]; + int16_t nf_ext[AR_MAX_CHAINS]; + } nf_hist[ATHN_NF_CAL_HIST_MAX]; + int nf_hist_cur; + int nf_hist_nvalid; + int16_t nf_priv[AR_MAX_CHAINS]; + int16_t nf_ext_priv[AR_MAX_CHAINS]; + int nf_calib_pending; + int nf_calib_ticks; + int pa_calib_ticks; + + struct athn_calib calib; + struct athn_ani ani; + +#if NBPFILTER > 0 + caddr_t sc_drvbpf; + + union { + struct athn_rx_radiotap_header th; + uint8_t pad[IEEE80211_RADIOTAP_HDRLEN]; + } sc_rxtapu; +#define sc_rxtap sc_rxtapu.th + int sc_rxtap_len; + + union { + struct athn_tx_radiotap_header th; + uint8_t pad[IEEE80211_RADIOTAP_HDRLEN]; + } sc_txtapu; +#define sc_txtap sc_txtapu.th + int sc_txtap_len; +#endif +}; + +#define ATHN_LOCK(sc) mtx_lock(&(sc)->sc_mtx) +#define ATHN_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) +#define ATHN_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) + +extern int athn_attach(struct athn_softc *); +extern int athn_like_otus_attach(struct athn_softc *); +extern void athn_detach(struct athn_softc *); +extern void athn_suspend(struct athn_softc *); +extern void athn_wakeup(struct athn_softc *); +extern int athn_intr(void *); +#endif diff --git a/sys/dev/athn/headers/if_athn_usb.h b/sys/dev/athn/headers/if_athn_usb.h new file mode 100644 --- /dev/null +++ b/sys/dev/athn/headers/if_athn_usb.h @@ -0,0 +1,533 @@ +/* $OpenBSD: if_athn_usb.h,v 1.13 2022/01/09 05:43:00 jsg Exp $ */ + +/*- + * Copyright (c) 2011 Damien Bergamini + * Copyright (c) 2018 Stefan Sperling + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef IF_ATHN_USB_H +#define IF_ATHN_USB_H + +/* Maximum number of STAs firmware can handle. */ +#define AR_USB_MAX_STA 8 + +#define AR_USB_DEFAULT_NF (-95) + +/* USB requests. */ +#define AR_FW_DOWNLOAD 0x30 +#define AR_FW_DOWNLOAD_COMP 0x31 + +/* USB endpoints addresses. */ +#define AR_PIPE_TX_DATA (UE_DIR_OUT | 1) +#define AR_PIPE_RX_DATA (UE_DIR_IN | 2) +#define AR_PIPE_RX_INTR (UE_DIR_IN | 3) +#define AR_PIPE_TX_INTR (UE_DIR_OUT | 4) + +/* Wireless module interface commands. */ +#define AR_WMI_CMD_ECHO 0x001 +#define AR_WMI_CMD_ACCESS_MEMORY 0x002 +#define AR_WMI_GET_FW_VERSION 0x003 +#define AR_WMI_CMD_DISABLE_INTR 0x004 +#define AR_WMI_CMD_ENABLE_INTR 0x005 +#define AR_WMI_CMD_ATH_INIT 0x006 +#define AR_WMI_CMD_ABORT_TXQ 0x007 +#define AR_WMI_CMD_STOP_TX_DMA 0x008 +#define AR_WMI_CMD_ABORT_TX_DMA 0x009 +#define AR_WMI_CMD_DRAIN_TXQ 0x00a +#define AR_WMI_CMD_DRAIN_TXQ_ALL 0x00b +#define AR_WMI_CMD_START_RECV 0x00c +#define AR_WMI_CMD_STOP_RECV 0x00d +#define AR_WMI_CMD_FLUSH_RECV 0x00e +#define AR_WMI_CMD_SET_MODE 0x00f +#define AR_WMI_CMD_NODE_CREATE 0x010 +#define AR_WMI_CMD_NODE_REMOVE 0x011 +#define AR_WMI_CMD_VAP_REMOVE 0x012 +#define AR_WMI_CMD_VAP_CREATE 0x013 +#define AR_WMI_CMD_REG_READ 0x014 +#define AR_WMI_CMD_REG_WRITE 0x015 +#define AR_WMI_CMD_RC_STATE_CHANGE 0x016 +#define AR_WMI_CMD_RC_RATE_UPDATE 0x017 +#define AR_WMI_CMD_TARGET_IC_UPDATE 0x018 +#define AR_WMI_CMD_TX_AGGR_ENABLE 0x019 +#define AR_WMI_CMD_TGT_DETACH 0x020 +#define AR_WMI_CMD_NODE_UPDATE 0x021 +#define AR_WMI_CMD_INT_STATS 0x022 +#define AR_WMI_CMD_TX_STATS 0x023 +#define AR_WMI_CMD_RX_STATS 0x024 +#define AR_WMI_CMD_BITRATE_MASK 0x025 +#define AR_WMI_CMD_REG_RMW 0x026 + +/* Wireless module interface events. */ +#define AR_WMI_EVT_TGT_RDY 0x001 +#define AR_WMI_EVT_SWBA 0x002 +#define AR_WMI_EVT_FATAL 0x003 +#define AR_WMI_EVT_TXTO 0x004 +#define AR_WMI_EVT_BMISS 0x005 +#define AR_WMI_EVT_DELBA 0x006 +#define AR_WMI_EVT_TXSTATUS 0x007 + +/* Structure for service AR_SVC_WMI_CONTROL. */ +struct ar_wmi_cmd_hdr { + uint16_t cmd_id; +#define AR_WMI_EVT_FLAG 0x1000 + + uint16_t seq_no; +} __packed; + +/* Values for AR_WMI_CMD_SET_MODE. */ +#define AR_HTC_MODE_11NA 0 +#define AR_HTC_MODE_11NG 1 + +#define AR_MAX_WRITE_COUNT 32 +/* Structure for command AR_WMI_CMD_REG_WRITE. */ +struct ar_wmi_cmd_reg_write { + uint32_t addr; + uint32_t val; +} __packed; + +/* Structure for command AR_WMI_CMD_NODE_{CREATE,REMOVE}. */ +struct ar_htc_target_sta { + uint8_t macaddr[IEEE80211_ADDR_LEN]; + uint8_t bssid[IEEE80211_ADDR_LEN]; + uint8_t sta_index; + uint8_t vif_index; + uint8_t is_vif_sta; + uint16_t flags; +#define AR_HTC_STA_AUTH 0x0001 +#define AR_HTC_STA_QOS 0x0002 +#define AR_HTC_STA_ERP 0x0004 +#define AR_HTC_STA_HT 0x0008 + + uint16_t htcap; + uint16_t maxampdu; + uint8_t pad; + + /* Internal state. */ + uint16_t txseqmgmt; + uint16_t iv16; + uint32_t iv32; + void *ni_vap; +} __packed; + +/* Structures for command AR_WMI_CMD_RC_RATE_UPDATE. */ +#define AR_HTC_RATE_MAX 30 +struct ar_htc_rateset { + uint8_t rs_nrates; + uint8_t rs_rates[AR_HTC_RATE_MAX]; +} __packed; + +struct ar_htc_target_rate { + uint8_t sta_index; + uint8_t isnew; + uint8_t pad[2]; + uint32_t capflags; +#define AR_RC_DS_FLAG 0x00000001 +#define AR_RC_40_FLAG 0x00000002 +#define AR_RC_SGI_FLAG 0x00000004 +#define AR_RC_HT_FLAG 0x00000008 +#define AR_RC_STBC_FLAG 0x00000030 /* 2 bits */ +#define AR_RC_WEP_TKIP_FLAG 0x00000100 + + struct ar_htc_rateset lg_rates; + struct ar_htc_rateset ht_rates; +} __packed; + +/* Structure for command AR_WMI_CMD_TX_AGGR_ENABLE. */ +struct ar_htc_target_aggr { + uint8_t sta_index; + uint8_t tidno; + uint8_t aggr_enable; + uint8_t padding; +} __packed; + +/* Structure for command AR_WMI_CMD_VAP_CREATE. */ +struct ar_htc_target_vif { + uint8_t index; + uint32_t opmode; +#define AR_HTC_M_IBSS 0 +#define AR_HTC_M_STA 1 +#define AR_HTC_M_WDS 2 +#define AR_HTC_M_AHDEMO 3 +#define AR_HTC_M_HOSTAP 6 +#define AR_HTC_M_MONITOR 8 + uint8_t myaddr[IEEE80211_ADDR_LEN]; + uint8_t ath_cap; + uint16_t rtsthreshold; + uint8_t pad; + + /* Internal state. */ + int8_t nodeindex; + void *iv_bss; +} __packed; + +/* Structure for command AM_WMI_CMD_TARGET_IC_UPDATE. */ +struct ar_htc_cap_target { + uint32_t ampdu_limit; + uint8_t ampdu_subframes; + uint8_t enable_coex; + uint8_t txchainmask; + uint8_t pad; +} __packed; + +struct ar_wmi_evt_txstatus { + uint8_t cookie; + + /* + * Legacy rates are indicated as rate array indices. + * HT rates are indicated as MCS indices. + */ + uint8_t rate; +#define AR_HTC_TXSTAT_RATE 0x0f +#define AR_HTC_TXSTAT_EPID 0xf0 +#define AR_HTC_TXSTAT_EPID_SHIFT 4 + + uint8_t flags; +#define AR_HTC_TXSTAT_ACK 0x01 +#define AR_HTC_TXSTAT_FILT 0x02 +#define AR_HTC_TXSTAT_RTC_CTS 0x04 +#define AR_HTC_TXSTAT_MCS 0x08 +#define AR_HTC_TXSTAT_CW40 0x10 +#define AR_HTC_TXSTAT_SGI 0x20 +} __packed; + +/* Structure for event AR_WMI_EVT_TXSTATUS. */ +#define AR_HTC_MAX_TX_STATUS 12 +struct ar_wmi_evt_txstatus_list { + uint8_t count; + struct ar_wmi_evt_txstatus ts[AR_HTC_MAX_TX_STATUS]; +} __packed; + +/* HTC header. */ +struct ar_htc_frame_hdr { + uint8_t endpoint_id; + uint8_t flags; +#define AR_HTC_FLAG_NEED_CREDIT_UPDATE 0x01 +#define AR_HTC_FLAG_TRAILER 0x02 +#define AR_HTC_FLAG_CREDIT_REDISTRIBUTION 0x03 + + uint16_t payload_len; + uint8_t control[4]; +} __packed; + +/* Structure for HTC endpoint id 0. */ +struct ar_htc_msg_hdr { + uint16_t msg_id; +#define AR_HTC_MSG_READY 0x0001 +#define AR_HTC_MSG_CONN_SVC 0x0002 +#define AR_HTC_MSG_CONN_SVC_RSP 0x0003 +#define AR_HTC_MSG_SETUP_COMPLETE 0x0004 +#define AR_HTC_MSG_CONF_PIPE 0x0005 +#define AR_HTC_MSG_CONF_PIPE_RSP 0x0006 +/* TODO: Mikolaj F.: Created to wait for result of AR_WMI_GET_FW_VERSION command. + * Consider if every WMI command shall have own id or a 1 common is fine. + */ +#define AR_WMI_CMD_MSG 0x0007 +} __packed; + +/* Structure for services AR_SVC_WMI_DATA_{VO,VI,BE,BK}. */ +struct ar_tx_frame { + uint8_t data_type; +#define AR_HTC_AMPDU 1 +#define AR_HTC_NORMAL 2 + + uint8_t node_idx; + uint8_t vif_idx; + uint8_t tid; + uint32_t flags; +#define AR_HTC_TX_CTSONLY 0x00000001 +#define AR_HTC_TX_RTSCTS 0x00000002 +#define AR_HTC_TX_USE_MIN_RATE 0x00000100 + + uint8_t key_type; + uint8_t key_idx; + uint8_t cookie; + uint8_t pad; +} __packed; + +/* Structure for service AR_SVC_WMI_MGMT. */ +struct ar_tx_mgmt { + uint8_t node_idx; + uint8_t vif_idx; + uint8_t tid; + uint8_t flags; + uint8_t key_type; + uint8_t key_idx; + uint8_t cookie; + uint8_t pad; +} __packed; + +/* Structure for service AR_SVC_WMI_BEACON. */ +struct ar_tx_bcn { + uint8_t len_changed; + uint8_t vif_idx; + uint16_t rev; +} __packed; + +/* Structure for message AR_HTC_MSG_READY. */ +struct ar_htc_msg_ready { + uint16_t credits; + uint16_t credits_size; + uint8_t max_endpoints; + uint8_t reserved; +} __packed; + +/* Structure for message AR_HTC_MSG_CONF_PIPE. */ +struct ar_htc_msg_config_pipe { + uint8_t pipe_id; + uint8_t credits; +} __packed; + +/* Structure for message AR_HTC_MSG_CONN_SVC. */ +struct ar_htc_msg_conn_svc { + uint16_t svc_id; + uint16_t conn_flags; + uint8_t dl_pipeid; + uint8_t ul_pipeid; + uint8_t svc_meta_len; + uint8_t reserved; +} __packed; + +/* Structure for message AR_HTC_MSG_CONN_SVC_RSP. */ +struct ar_htc_msg_conn_svc_rsp { + uint16_t svc_id; + uint8_t status; +#define AR_HTC_SVC_SUCCESS 0 +#define AR_HTC_SVC_NOT_FOUND 1 +#define AR_HTC_SVC_FAILED 2 +#define AR_HTC_SVC_NO_RESOURCES 3 +#define AR_HTC_SVC_NO_MORE_EP 4 + + uint8_t endpoint_id; + uint16_t max_msg_len; + uint8_t svc_meta_len; + uint8_t reserved; +} __packed; + +#define AR_SVC(grp, idx) ((grp) << 8 | (idx)) +#define AR_SVC_IDX(svc) ((svc) & 0xff) +/* Service groups. */ +#define AR_SVC_GRP_RSVD 0 +#define AR_SVC_GRP_WMI 1 +/* Service identifiers for WMI group. */ +#define AR_SVC_WMI_CONTROL AR_SVC(AR_SVC_GRP_WMI, 0) +#define AR_SVC_WMI_BEACON AR_SVC(AR_SVC_GRP_WMI, 1) +#define AR_SVC_WMI_CAB AR_SVC(AR_SVC_GRP_WMI, 2) +#define AR_SVC_WMI_UAPSD AR_SVC(AR_SVC_GRP_WMI, 3) +#define AR_SVC_WMI_MGMT AR_SVC(AR_SVC_GRP_WMI, 4) +#define AR_SVC_WMI_DATA_VO AR_SVC(AR_SVC_GRP_WMI, 5) +#define AR_SVC_WMI_DATA_VI AR_SVC(AR_SVC_GRP_WMI, 6) +#define AR_SVC_WMI_DATA_BE AR_SVC(AR_SVC_GRP_WMI, 7) +#define AR_SVC_WMI_DATA_BK AR_SVC(AR_SVC_GRP_WMI, 8) + +struct ar_stream_hdr { + uint16_t len; + uint16_t tag; +#define AR_USB_RX_STREAM_TAG 0x4e00 +#define AR_USB_TX_STREAM_TAG 0x697e +} __packed __attribute__((aligned(4))); + +#define AR_MAX_CHAINS 3 + +/* Rx descriptor. */ +struct ar_rx_status { + uint64_t rs_tstamp; + uint16_t rs_datalen; + uint8_t rs_status; +#define AR_RXS_RXERR_CRC 0x01 +#define AR_RXS_RXERR_PHY 0x02 +#define AR_RXS_RXERR_FIFO 0x04 +#define AR_RXS_RXERR_DECRYPT 0x08 +#define AR_RXS_RXERR_MIC 0x10 + uint8_t rs_phyerr; + int8_t rs_rssi; + int8_t rs_rssi_ctl[AR_MAX_CHAINS]; + int8_t rs_rssi_ext[AR_MAX_CHAINS]; + uint8_t rs_keyix; + uint8_t rs_rate; + uint8_t rs_antenna; + uint8_t rs_more; + uint8_t rs_isaggr; + uint8_t rs_moreaggr; + uint8_t rs_num_delims; + uint8_t rs_flags; +#define AR_RXS_FLAG_GI 0x04 +#define AR_RXS_FLAG_2040 0x08 + + uint8_t rs_dummy; + uint32_t rs_evm[AR_MAX_CHAINS]; +} __packed __attribute__((aligned(4))); + +/* Structure to read major and minor version via WMI */ +struct ar_wmi_fw_version { + uint16_t major; + uint16_t minor; +} __packed; + +/* + * Driver definitions. + */ +enum { + ATHN_BULK_TX, + ATHN_BULK_RX, + ATHN_BULK_IRQ, + ATHN_BULK_CMD, + ATHN_N_XFER +}; + +#define ATHN_USB_RX_LIST_COUNT 1 +#define ATHN_USB_TX_LIST_COUNT (8 + 1) /* NB: +1 for beacons. */ + +#define ATHN_USB_HOST_CMD_RING_COUNT 32 + +#define ATHN_USB_RXBUFSZ (8 * 1024) /* XXX Linux 16K */ +#define ATHN_USB_TXBUFSZ \ + ((sizeof(struct ar_stream_hdr) + \ + sizeof(struct ar_htc_frame_hdr) + \ + sizeof(struct ar_tx_frame) + \ + IEEE80211_MAX_LEN + 3) & ~3) +#define ATHN_USB_TXCMDSZ 512 + +#define ATHN_USB_TX_TIMEOUT 5000 /* ms */ +#define ATHN_USB_CMD_TIMEOUT 1000 /* ms */ + +struct athn_usb_softc; + +struct athn_usb_rx_stream { + struct mbuf *m; + int moff; + int left; +}; + +struct athn_usb_rx_data { + struct athn_usb_softc *sc; + struct usb_xfer *xfer; + char *buf; +}; + +// TODO: to be removed. Replaced by athn_usb_data +#if OpenBSD_ONLY +struct athn_usb_tx_data { + struct athn_usb_softc *sc; + struct usb_xfer *xfer; + char *buf; + TAILQ_ENTRY(athn_usb_tx_data) next; +}; +#endif +struct athn_usb_data { + struct athn_usb_softc *usc; + struct usb_xfer *xfer; + char *buf; + usb_frlength_t buflen; + struct mbuf *m; + struct ieee80211_node *ni; + STAILQ_ENTRY(athn_usb_data) next; +}; + +struct athn_usb_host_cmd { + void (*cb)(struct athn_usb_softc *, void *); + char data[256]; +}; + +struct athn_usb_cmd_newstate { + enum ieee80211_state state; + int arg; +}; + +struct athn_usb_cmd_key { + struct ieee80211_node *ni; + struct ieee80211_key *key; +}; + +struct athn_usb_aggr_cmd { + int8_t sta_index; + int8_t tid; +}; + +struct athn_usb_host_cmd_ring { + struct athn_usb_host_cmd cmd[ATHN_USB_HOST_CMD_RING_COUNT]; + int cur; + int next; + int queued; +}; + +struct athn_usb_softc { + struct athn_softc sc_sc; +#define usb_dev sc_sc.sc_dev + int sc_athn_attached; + + /* USB specific goo. */ + struct usb_device *sc_udev; + struct usb_interface *sc_iface; + + u_int flags; +#define ATHN_USB_FLAG_AR7010 0x01 + + struct athn_usb_rx_stream rx_stream; + + uint8_t *ibuf; + size_t ibuflen; + + struct ar_wmi_cmd_reg_write wbuf[AR_MAX_WRITE_COUNT]; + int wcount; + + uint16_t wmi_seq_no; + uint16_t wait_cmd_id; + uint16_t wait_msg_id; + void *obuf; + struct ar_htc_msg_conn_svc_rsp *msg_conn_svc_rsp; + + struct usb_xfer *sc_xfer[ATHN_N_XFER]; + +// struct athn_usb_host_cmd_ring cmdq; + struct athn_usb_data rx_data[ATHN_USB_RX_LIST_COUNT]; + struct athn_usb_data tx_data[ATHN_USB_TX_LIST_COUNT]; + struct athn_usb_data tx_cmd[ATHN_USB_HOST_CMD_RING_COUNT]; +// TAILQ_HEAD(, athn_usb_tx_data) tx_free_list; +// struct athn_usb_host_cmd tx_cmd; +// struct athn_usb_host_cmd *tx_bcn; + + int sc_tx_n_active; + + STAILQ_HEAD(, athn_usb_data) sc_rx_active; + STAILQ_HEAD(, athn_usb_data) sc_rx_inactive; + STAILQ_HEAD(, athn_usb_data) sc_tx_active[ATHN_N_XFER]; + STAILQ_HEAD(, athn_usb_data) sc_tx_inactive; + STAILQ_HEAD(, athn_usb_data) sc_tx_pending[ATHN_N_XFER]; + + STAILQ_HEAD(, athn_usb_data) sc_cmd_active; + STAILQ_HEAD(, athn_usb_data) sc_cmd_inactive; + STAILQ_HEAD(, athn_usb_data) sc_cmd_pending; + STAILQ_HEAD(, athn_usb_data) sc_cmd_waiting; + + uint8_t ep_ctrl; + uint8_t ep_bcn; + uint8_t ep_cab; + uint8_t ep_uapsd; + uint8_t ep_mgmt; + uint8_t ep_data[ATHN_N_XFER]; + + /* + * Firmware cannot handle more than 8 STAs. + * We use a bitmask to keep track of available slots in the firmware's + * node array. A 1 bit at index N, as determined by ffs(3), means the + * slot at this index is available. + */ + uint8_t free_node_slots; + + void (*sc_node_free)(struct ieee80211com *, + struct ieee80211_node *); + int sc_key_tasks; +}; + +#endif diff --git a/sys/dev/athn/headers/if_athn_usb_fw.h b/sys/dev/athn/headers/if_athn_usb_fw.h new file mode 100644 --- /dev/null +++ b/sys/dev/athn/headers/if_athn_usb_fw.h @@ -0,0 +1,9 @@ +#ifndef IF_ATHN_USB_FW_H +#define IF_ATHN_USB_FW_H + +struct athn_usb_softc; + +int athn_usb_load_firmware(struct athn_usb_softc *, struct ar_wmi_fw_version *); +const struct firmware* athn_usb_unload_firmware(); + +#endif /* IF_ATHN_USB_FW_H */ \ No newline at end of file diff --git a/sys/dev/athn/headers/openbsd/openbsd_usbdevs.h b/sys/dev/athn/headers/openbsd/openbsd_usbdevs.h new file mode 100644 --- /dev/null +++ b/sys/dev/athn/headers/openbsd/openbsd_usbdevs.h @@ -0,0 +1,4782 @@ +/* $OpenBSD: usbdevs.h,v 1.768 2023/05/10 18:26:43 miod Exp $ */ + +/* + * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + * + * generated from: + * OpenBSD: usbdevs,v 1.756 2023/05/10 18:26:05 miod Exp + */ +/* $NetBSD: usbdevs,v 1.322 2003/05/10 17:47:14 hamajima Exp $ */ + +/* + * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lennart@augustsson.net) at + * Carlstedt Research & Technology. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * List of known USB vendors + * + * Please note that these IDs do not do anything. Adding an ID here and + * regenerating the usbdevs.h and usbdevs_data.h only makes a symbolic name + * available to the source code and does not change any functionality, nor + * does it make your device available to a specific driver. + * It will however make the descriptive string available if a device does not + * provide the string itself. + * + * After adding a vendor ID VNDR and a product ID PRDCT you will have the + * following extra defines: + * #define USB_VENDOR_VNDR 0x???? + * #define USB_PRODUCT_VNDR_PRDCT 0x???? + * + * You may have to add these defines to the respective probe routines to + * make the device recognised by the appropriate device driver. + */ + +#define USB_VENDOR_PLANEX4 0x0053 /* Planex Communications */ +#define USB_VENDOR_UNKNOWN2 0x0105 /* Unknown vendor */ +#define USB_VENDOR_EGALAX2 0x0123 /* eGalax */ +#define USB_VENDOR_UNKNOWN6 0x01e1 /* Unknown vendor */ +#define USB_VENDOR_HUMAX 0x02ad /* HUMAX */ +#define USB_VENDOR_BWCT 0x03da /* Bernd Walter Computer Technology */ +#define USB_VENDOR_AOX 0x03e8 /* AOX */ +#define USB_VENDOR_ATMEL 0x03eb /* Atmel */ +#define USB_VENDOR_MITSUMI 0x03ee /* Mitsumi */ +#define USB_VENDOR_HP 0x03f0 /* Hewlett Packard */ +#define USB_VENDOR_ADAPTEC 0x03f3 /* Adaptec */ +#define USB_VENDOR_NATIONAL 0x0400 /* National Semiconductor */ +#define USB_VENDOR_ACERLABS 0x0402 /* Acer Labs */ +#define USB_VENDOR_FTDI 0x0403 /* Future Technology Devices */ +#define USB_VENDOR_QUANTA2 0x0408 /* Quanta */ +#define USB_VENDOR_NEC 0x0409 /* NEC */ +#define USB_VENDOR_KODAK 0x040a /* Eastman Kodak */ +#define USB_VENDOR_VIA 0x040d /* VIA */ +#define USB_VENDOR_MELCO 0x0411 /* Melco */ +#define USB_VENDOR_LEADTEK 0x0413 /* Leadtek */ +#define USB_VENDOR_CREATIVE 0x041e /* Creative Labs */ +#define USB_VENDOR_NOKIA2 0x0421 /* Nokia */ +#define USB_VENDOR_ADI 0x0422 /* ADI Systems */ +#define USB_VENDOR_CATC 0x0423 /* Computer Access Technology */ +#define USB_VENDOR_SMC2 0x0424 /* Standard Microsystems */ +#define USB_VENDOR_GRAVIS 0x0428 /* Advanced Gravis Computer */ +#define USB_VENDOR_FUJITSUCOMP 0x0430 /* Fujitsu Component */ +#define USB_VENDOR_TAUGA 0x0436 /* Taugagreining HF */ +#define USB_VENDOR_AMD 0x0438 /* Advanced Micro Devices */ +#define USB_VENDOR_LEXMARK 0x043d /* Lexmark International */ +#define USB_VENDOR_LG 0x043e /* LG USA */ +#define USB_VENDOR_NANAO 0x0440 /* NANAO */ +#define USB_VENDOR_ALPS 0x044e /* Alps Electric */ +#define USB_VENDOR_THRUST 0x044f /* Thrustmaster */ +#define USB_VENDOR_TI 0x0451 /* Texas Instruments */ +#define USB_VENDOR_ANALOGDEVICES 0x0456 /* Analog Devices */ +#define USB_VENDOR_SIS 0x0457 /* Silicon Integrated Systems Corp. */ +#define USB_VENDOR_KYE 0x0458 /* KYE Systems */ +#define USB_VENDOR_DIAMOND2 0x045a /* Diamond (Supra) */ +#define USB_VENDOR_RENESAS 0x045b /* Renesas */ +#define USB_VENDOR_MICROSOFT 0x045e /* Microsoft */ +#define USB_VENDOR_PRIMAX 0x0461 /* Primax Electronics */ +#define USB_VENDOR_MGE 0x0463 /* Eaton (MGE) */ +#define USB_VENDOR_AMP 0x0464 /* AMP */ +#define USB_VENDOR_CHERRY 0x046a /* Cherry Mikroschalter */ +#define USB_VENDOR_MEGATRENDS 0x046b /* American Megatrends */ +#define USB_VENDOR_LOGITECH 0x046d /* Logitech */ +#define USB_VENDOR_BTC 0x046e /* Behavior Tech. Computer */ +#define USB_VENDOR_PHILIPS 0x0471 /* Philips */ +#define USB_VENDOR_SANYO 0x0474 /* Sanyo Electric */ +#define USB_VENDOR_CONNECTIX 0x0478 /* Connectix */ +#define USB_VENDOR_DELL2 0x047c /* Dell */ +#define USB_VENDOR_KENSINGTON 0x047d /* Kensington */ +#define USB_VENDOR_LUCENT 0x047e /* Lucent */ +#define USB_VENDOR_PLANTRONICS 0x047f /* Plantronics */ +#define USB_VENDOR_KYOCERA 0x0482 /* Kyocera */ +#define USB_VENDOR_STMICRO 0x0483 /* STMicroelectronics */ +#define USB_VENDOR_FOXCONN 0x0489 /* Foxconn */ +#define USB_VENDOR_YAMAHA 0x0499 /* YAMAHA */ +#define USB_VENDOR_COMPAQ 0x049f /* Compaq */ +#define USB_VENDOR_HITACHI 0x04a4 /* Hitachi */ +#define USB_VENDOR_ACERP 0x04a5 /* Acer Peripherals */ +#define USB_VENDOR_DAVICOM 0x04a6 /* Davicom */ +#define USB_VENDOR_VISIONEER 0x04a7 /* Visioneer */ +#define USB_VENDOR_CANON 0x04a9 /* Canon */ +#define USB_VENDOR_NIKON 0x04b0 /* Nikon */ +#define USB_VENDOR_IBM 0x04b3 /* IBM */ +#define USB_VENDOR_CYPRESS 0x04b4 /* Cypress Semiconductor */ +#define USB_VENDOR_EPSON 0x04b8 /* Seiko Epson */ +#define USB_VENDOR_RAINBOW 0x04b9 /* Rainbow Technologies */ +#define USB_VENDOR_IODATA 0x04bb /* I/O Data */ +#define USB_VENDOR_TDK 0x04bf /* TDK */ +#define USB_VENDOR_3COMUSR 0x04c1 /* U.S. Robotics */ +#define USB_VENDOR_METHODE 0x04c2 /* Methode Electronics Far East */ +#define USB_VENDOR_MAXISWITCH 0x04c3 /* Maxi Switch */ +#define USB_VENDOR_LOCKHEEDMER 0x04c4 /* Lockheed Martin Energy Research */ +#define USB_VENDOR_FUJITSU 0x04c5 /* Fujitsu */ +#define USB_VENDOR_TOSHIBAAM 0x04c6 /* Toshiba America */ +#define USB_VENDOR_MICROMACRO 0x04c7 /* Micro Macro Technologies */ +#define USB_VENDOR_KONICA 0x04c8 /* Konica */ +#define USB_VENDOR_LITEON 0x04ca /* Lite-On Technology */ +#define USB_VENDOR_FUJIPHOTO 0x04cb /* Fuji Photo Film */ +#define USB_VENDOR_PHILIPSSEMI 0x04cc /* Philips Semiconductors */ +#define USB_VENDOR_TATUNG 0x04cd /* Tatung Co. Of America */ +#define USB_VENDOR_SCANLOGIC 0x04ce /* ScanLogic */ +#define USB_VENDOR_MYSON 0x04cf /* Myson Technology */ +#define USB_VENDOR_DIGI2 0x04d0 /* Digi */ +#define USB_VENDOR_ITTCANON 0x04d1 /* ITT Canon */ +#define USB_VENDOR_ALTEC 0x04d2 /* Altec Lansing */ +#define USB_VENDOR_MICROCHIP 0x04d8 /* Microchip Technology, Inc. */ +#define USB_VENDOR_HOLTEK 0x04d9 /* Holtek */ +#define USB_VENDOR_PANASONIC 0x04da /* Panasonic (Matsushita) */ +#define USB_VENDOR_SHARP 0x04dd /* Sharp */ +#define USB_VENDOR_IIYAMA 0x04e1 /* Iiyama */ +#define USB_VENDOR_EXAR 0x04e2 /* Exar */ +#define USB_VENDOR_SHUTTLE 0x04e6 /* Shuttle Technology */ +#define USB_VENDOR_SAMSUNG2 0x04e8 /* Samsung Electronics */ +#define USB_VENDOR_ANNABOOKS 0x04ed /* Annabooks */ +#define USB_VENDOR_JVC 0x04f1 /* JVC */ +#define USB_VENDOR_CHICONY 0x04f2 /* Chicony Electronics */ +#define USB_VENDOR_ELAN 0x04f3 /* Elan */ +#define USB_VENDOR_BROTHER 0x04f9 /* Brother Industries */ +#define USB_VENDOR_DALLAS 0x04fa /* Dallas Semiconductor */ +#define USB_VENDOR_ACER 0x0502 /* Acer */ +#define USB_VENDOR_3COM 0x0506 /* 3Com */ +#define USB_VENDOR_AZTECH 0x0509 /* Aztech Systems */ +#define USB_VENDOR_BELKIN 0x050d /* Belkin Components */ +#define USB_VENDOR_KAWATSU 0x050f /* Kawatsu Semiconductor */ +#define USB_VENDOR_APC 0x051d /* American Power Conversion */ +#define USB_VENDOR_CONNECTEK 0x0522 /* Advanced Connectek USA */ +#define USB_VENDOR_NETCHIP 0x0525 /* NetChip Technology */ +#define USB_VENDOR_ALTRA 0x0527 /* ALTRA */ +#define USB_VENDOR_ATI 0x0528 /* ATI Technologies */ +#define USB_VENDOR_AKS 0x0529 /* Aladdin Knowledge Systems */ +#define USB_VENDOR_UNIACCESS 0x0540 /* Universal Access */ +#define USB_VENDOR_VIEWSONIC 0x0543 /* ViewSonic */ +#define USB_VENDOR_XIRLINK 0x0545 /* Xirlink */ +#define USB_VENDOR_ANCHOR 0x0547 /* Anchor Chips */ +#define USB_VENDOR_SONY 0x054c /* Sony */ +#define USB_VENDOR_VISION 0x0553 /* VLSI Vision */ +#define USB_VENDOR_ASAHIKASEI 0x0556 /* Asahi Kasei Microsystems */ +#define USB_VENDOR_ATEN 0x0557 /* ATEN International */ +#define USB_VENDOR_SAMSUNG 0x055d /* Samsung */ +#define USB_VENDOR_MUSTEK 0x055f /* Mustek Systems */ +#define USB_VENDOR_TELEX 0x0562 /* Telex Communications */ +#define USB_VENDOR_PERACOM 0x0565 /* Peracom Networks */ +#define USB_VENDOR_ALCOR2 0x0566 /* Alcor Micro */ +#define USB_VENDOR_WACOM 0x056a /* WACOM */ +#define USB_VENDOR_ETEK 0x056c /* e-TEK Labs */ +#define USB_VENDOR_EIZO 0x056d /* EIZO */ +#define USB_VENDOR_ELECOM 0x056e /* Elecom */ +#define USB_VENDOR_XYRATEX 0x0572 /* Xyratex */ +#define USB_VENDOR_HAUPPAUGE 0x0573 /* Hauppauge Computer Works */ +#define USB_VENDOR_BAFO 0x0576 /* BAFO/Quality Computer Accessories */ +#define USB_VENDOR_YEDATA 0x057b /* Y-E Data */ +#define USB_VENDOR_AVM 0x057c /* AVM */ +#define USB_VENDOR_QUICKSHOT 0x057f /* Quickshot */ +#define USB_VENDOR_ROLAND 0x0582 /* Roland */ +#define USB_VENDOR_ROCKFIRE 0x0583 /* Rockfire */ +#define USB_VENDOR_RATOC 0x0584 /* RATOC Systems */ +#define USB_VENDOR_ZYXEL 0x0586 /* ZyXEL Communication */ +#define USB_VENDOR_ALCOR 0x058f /* Alcor Micro */ +#define USB_VENDOR_OMRON 0x0590 /* OMRON Corporation */ +#define USB_VENDOR_IOMEGA 0x059b /* Iomega */ +#define USB_VENDOR_ATREND 0x059c /* A-Trend Technology */ +#define USB_VENDOR_AID 0x059d /* Advanced Input Devices */ +#define USB_VENDOR_LACIE 0x059f /* LaCie */ +#define USB_VENDOR_THRUSTMASTER 0x05a4 /* Thrustmaster */ +#define USB_VENDOR_CISCOLINKSYS3 0x05a6 /* Cisco-Linksys */ +#define USB_VENDOR_OMNIVISION 0x05a9 /* OmniVision */ +#define USB_VENDOR_INSYSTEM 0x05ab /* In-System Design */ +#define USB_VENDOR_APPLE 0x05ac /* Apple Computer */ +#define USB_VENDOR_YCCABLE 0x05ad /* Y.C. Cable */ +#define USB_VENDOR_JINGMOLD 0x05af /* Jing Mold */ +#define USB_VENDOR_DIGI 0x05c5 /* Digi International */ +#define USB_VENDOR_QUALCOMM 0x05c6 /* Qualcomm */ +#define USB_VENDOR_QTRONIX 0x05c7 /* Qtronix */ +#define USB_VENDOR_RICOH 0x05ca /* Ricoh */ +#define USB_VENDOR_ELSA 0x05cc /* ELSA */ +#define USB_VENDOR_BRAINBOXES 0x05d1 /* Brainboxes */ +#define USB_VENDOR_ULTIMA 0x05d8 /* Ultima */ +#define USB_VENDOR_AXIOHM 0x05d9 /* Axiohm Transaction Solutions */ +#define USB_VENDOR_MICROTEK 0x05da /* Microtek */ +#define USB_VENDOR_SUNTAC 0x05db /* SUN Corporation */ +#define USB_VENDOR_LEXAR 0x05dc /* Lexar Media */ +#define USB_VENDOR_ADDTRON 0x05dd /* Addtron */ +#define USB_VENDOR_SYMBOL 0x05e0 /* Symbol Technologies */ +#define USB_VENDOR_GENESYS 0x05e3 /* Genesys Logic */ +#define USB_VENDOR_FUJI 0x05e5 /* Fuji Electric */ +#define USB_VENDOR_KEITHLEY 0x05e6 /* Keithley Instruments */ +#define USB_VENDOR_EIZONANAO 0x05e7 /* EIZO Nanao */ +#define USB_VENDOR_KLSI 0x05e9 /* Kawasaki LSI */ +#define USB_VENDOR_FFC 0x05eb /* FFC */ +#define USB_VENDOR_ANKO 0x05ef /* Anko Electronic */ +#define USB_VENDOR_PIENGINEERING 0x05f3 /* P.I. Engineering */ +#define USB_VENDOR_AOC 0x05f6 /* AOC International */ +#define USB_VENDOR_CHIC 0x05fe /* Chic Technology */ +#define USB_VENDOR_BARCO 0x0600 /* Barco Display Systems */ +#define USB_VENDOR_BRIDGE 0x0607 /* Bridge Information */ +#define USB_VENDOR_SOLIDYEAR 0x060b /* Solid Year */ +#define USB_VENDOR_BIORAD 0x0614 /* Bio-Rad Laboratories */ +#define USB_VENDOR_MACALLY 0x0618 /* Macally */ +#define USB_VENDOR_ACTLABS 0x061c /* Act Labs */ +#define USB_VENDOR_ALARIS 0x0620 /* Alaris */ +#define USB_VENDOR_APEX 0x0624 /* Apex */ +#define USB_VENDOR_VIVITAR 0x0636 /* Vivitar */ +#define USB_VENDOR_GUNZE 0x0637 /* Gunze Electronics USA */ +#define USB_VENDOR_AVISION 0x0638 /* Avision */ +#define USB_VENDOR_TEAC 0x0644 /* TEAC */ +#define USB_VENDOR_SGI 0x065e /* Silicon Graphics */ +#define USB_VENDOR_SANWASUPPLY 0x0663 /* Sanwa Supply */ +#define USB_VENDOR_MUSTEK2 0x0665 /* Mustek Systems */ +#define USB_VENDOR_LINKSYS 0x066b /* Linksys */ +#define USB_VENDOR_ACERSA 0x066e /* Acer Semiconductor America */ +#define USB_VENDOR_SIGMATEL 0x066f /* Sigmatel */ +#define USB_VENDOR_DRAYTEK 0x0675 /* DrayTek */ +#define USB_VENDOR_AIWA 0x0677 /* Aiwa */ +#define USB_VENDOR_ACARD 0x0678 /* ACARD Technology */ +#define USB_VENDOR_PROLIFIC 0x067b /* Prolific Technology */ +#define USB_VENDOR_SIEMENS 0x067c /* Siemens */ +#define USB_VENDOR_AVANCELOGIC 0x0680 /* Avance Logic */ +#define USB_VENDOR_SIEMENS2 0x0681 /* Siemens */ +#define USB_VENDOR_MINOLTA 0x0686 /* Minolta */ +#define USB_VENDOR_CHPRODUCTS 0x068e /* CH Products */ +#define USB_VENDOR_HAGIWARA 0x0693 /* Hagiwara Sys-Com */ +#define USB_VENDOR_CTX 0x0698 /* Chuntex */ +#define USB_VENDOR_ASKEY 0x069a /* Askey Computer */ +#define USB_VENDOR_SAITEK 0x06a3 /* Saitek */ +#define USB_VENDOR_ALCATELT 0x06b9 /* Alcatel Telecom */ +#define USB_VENDOR_AGFA 0x06bd /* AGFA-Gevaert */ +#define USB_VENDOR_ASIAMD 0x06be /* Asia Microelectronic Development */ +#define USB_VENDOR_PHIDGETS 0x06c2 /* Phidgets */ +#define USB_VENDOR_BIZLINK 0x06c4 /* Bizlink International */ +#define USB_VENDOR_SYNAPTICS 0x06cb /* Synaptics */ +#define USB_VENDOR_KEYSPAN 0x06cd /* Keyspan */ +#define USB_VENDOR_AASHIMA 0x06d6 /* Aashima Technology */ +#define USB_VENDOR_LIEBERT 0x06da /* Liebert */ +#define USB_VENDOR_MULTITECH 0x06e0 /* MultiTech */ +#define USB_VENDOR_ADS 0x06e1 /* ADS Technologies */ +#define USB_VENDOR_ALCATELM 0x06e4 /* Alcatel Microelectronics */ +#define USB_VENDOR_SIRIUS 0x06ea /* Sirius Technologies */ +#define USB_VENDOR_GUILLEMOT 0x06f8 /* Guillemot */ +#define USB_VENDOR_BOSTON 0x06fd /* Boston Acoustics */ +#define USB_VENDOR_SMC 0x0707 /* Standard Microsystems */ +#define USB_VENDOR_PUTERCOM 0x0708 /* Putercom */ +#define USB_VENDOR_MCT 0x0711 /* MCT */ +#define USB_VENDOR_IMATION 0x0718 /* Imation */ +#define USB_VENDOR_DOMAIN 0x071b /* Domain Technologies, Inc. */ +#define USB_VENDOR_SUSTEEN 0x0731 /* Susteen */ +#define USB_VENDOR_EICON 0x0734 /* Eicon Networks */ +#define USB_VENDOR_STOLLMANN 0x0742 /* Stollmann */ +#define USB_VENDOR_SYNTECH 0x0745 /* Syntech Information */ +#define USB_VENDOR_DIGITALSTREAM 0x074e /* Digital Stream */ +#define USB_VENDOR_AUREAL 0x0755 /* Aureal Semiconductor */ +#define USB_VENDOR_IDOWELL 0x075d /* iDowell */ +#define USB_VENDOR_MIDIMAN 0x0763 /* Midiman */ +#define USB_VENDOR_CYBERPOWER 0x0764 /* CyberPower */ +#define USB_VENDOR_SURECOM 0x0769 /* Surecom Technology */ +#define USB_VENDOR_LINKSYS2 0x077b /* Linksys */ +#define USB_VENDOR_GRIFFIN 0x077d /* Griffin Technology */ +#define USB_VENDOR_SANDISK 0x0781 /* SanDisk */ +#define USB_VENDOR_JENOPTIK 0x0784 /* Jenoptik */ +#define USB_VENDOR_LOGITEC 0x0789 /* Logitec */ +#define USB_VENDOR_NOKIA 0x078b /* Nokia */ +#define USB_VENDOR_BRIMAX 0x078e /* Brimax */ +#define USB_VENDOR_AXIS 0x0792 /* Axis Communications */ +#define USB_VENDOR_ABL 0x0794 /* ABL Electronics */ +#define USB_VENDOR_SAGEM 0x079b /* Sagem */ +#define USB_VENDOR_SUNCOMM 0x079c /* Sun Communications */ +#define USB_VENDOR_ALFADATA 0x079d /* Alfadata Computer */ +#define USB_VENDOR_NATIONALTECH 0x07a2 /* National Technical Systems */ +#define USB_VENDOR_ONNTO 0x07a3 /* Onnto */ +#define USB_VENDOR_BE 0x07a4 /* Be */ +#define USB_VENDOR_ADMTEK 0x07a6 /* ADMtek */ +#define USB_VENDOR_COREGA 0x07aa /* Corega */ +#define USB_VENDOR_FREECOM 0x07ab /* Freecom */ +#define USB_VENDOR_MICROTECH 0x07af /* Microtech */ +#define USB_VENDOR_MOTOROLA3 0x07b2 /* Motorola */ +#define USB_VENDOR_OLYMPUS 0x07b4 /* Olympus */ +#define USB_VENDOR_ABOCOM 0x07b8 /* AboCom Systems */ +#define USB_VENDOR_KEISOKUGIKEN 0x07c1 /* Keisokugiken */ +#define USB_VENDOR_ONSPEC 0x07c4 /* OnSpec */ +#define USB_VENDOR_APG 0x07c5 /* APG Cash Drawer */ +#define USB_VENDOR_BUG 0x07c8 /* B.U.G. */ +#define USB_VENDOR_ALLIEDTELESYN 0x07c9 /* Allied Telesyn International */ +#define USB_VENDOR_AVERMEDIA 0x07ca /* AVerMedia Technologies */ +#define USB_VENDOR_SIIG 0x07cc /* SIIG */ +#define USB_VENDOR_CASIO 0x07cf /* CASIO */ +#define USB_VENDOR_DLINK2 0x07d1 /* D-Link */ +#define USB_VENDOR_APTIO 0x07d2 /* Aptio Products */ +#define USB_VENDOR_ARASAN 0x07da /* Arasan Chip Systems */ +#define USB_VENDOR_ALLIEDCABLE 0x07e6 /* Allied Cable */ +#define USB_VENDOR_STSN 0x07ef /* STSN */ +#define USB_VENDOR_BEWAN 0x07fa /* Bewan */ +#define USB_VENDOR_ZOOM 0x0803 /* Zoom Telephonics */ +#define USB_VENDOR_BROADLOGIC 0x0827 /* BroadLogic */ +#define USB_VENDOR_HANDSPRING 0x082d /* Handspring */ +#define USB_VENDOR_PALM 0x0830 /* Palm Computing */ +#define USB_VENDOR_SOURCENEXT 0x0833 /* SOURCENEXT */ +#define USB_VENDOR_ACTIONSTAR 0x0835 /* Action Star Enterprise */ +#define USB_VENDOR_ACCTON 0x083a /* Accton Technology */ +#define USB_VENDOR_DIAMOND 0x0841 /* Diamond */ +#define USB_VENDOR_NETGEAR 0x0846 /* BayNETGEAR */ +#define USB_VENDOR_TOPRE 0x0853 /* Topre Corporation */ +#define USB_VENDOR_ACTIVEWIRE 0x0854 /* ActiveWire */ +#define USB_VENDOR_BBELECTR 0x0856 /* B&B Electronics */ +#define USB_VENDOR_PORTGEAR 0x085a /* PortGear */ +#define USB_VENDOR_NETGEAR2 0x0864 /* Netgear */ +#define USB_VENDOR_SYSTEMTALKS 0x086e /* System Talks */ +#define USB_VENDOR_METRICOM 0x0870 /* Metricom */ +#define USB_VENDOR_ADESSOKBTEK 0x087c /* ADESSO/Kbtek America */ +#define USB_VENDOR_JATON 0x087d /* Jaton */ +#define USB_VENDOR_APT 0x0880 /* APT Technologies */ +#define USB_VENDOR_BOCARESEARCH 0x0885 /* Boca Research */ +#define USB_VENDOR_ANDREA 0x08a8 /* Andrea Electronics */ +#define USB_VENDOR_BURRBROWN 0x08bb /* Burr-Brown Japan */ +#define USB_VENDOR_2WIRE 0x08c8 /* 2Wire */ +#define USB_VENDOR_AIPTEK 0x08ca /* AIPTEK International */ +#define USB_VENDOR_SMARTBRIDGES 0x08d1 /* SmartBridges */ +#define USB_VENDOR_BILLIONTON 0x08dd /* Billionton Systems */ +#define USB_VENDOR_GEMPLUS 0x08e6 /* GEMPLUS */ +#define USB_VENDOR_EXTENDED 0x08e9 /* Extended Systems */ +#define USB_VENDOR_MSYSTEMS 0x08ec /* M-Systems */ +#define USB_VENDOR_DIGIANSWER 0x08fd /* Digianswer */ +#define USB_VENDOR_AUTHENTEC 0x08ff /* AuthenTec */ +#define USB_VENDOR_SIEMENS4 0x0908 /* Siemens */ +#define USB_VENDOR_AUDIOTECHNICA 0x0909 /* Audio-Technica */ +#define USB_VENDOR_TRUMPION 0x090a /* Trumpion Microelectronics */ +#define USB_VENDOR_ALATION 0x0910 /* Alation Systems */ +#define USB_VENDOR_GLOBESPAN 0x0915 /* Globespan */ +#define USB_VENDOR_CONCORDCAMERA 0x0919 /* Concord Camera */ +#define USB_VENDOR_GARMIN 0x091e /* Garmin International */ +#define USB_VENDOR_GOHUBS 0x0921 /* GoHubs */ +#define USB_VENDOR_BIOMETRIC 0x0929 /* American Biometric Company */ +#define USB_VENDOR_TOSHIBA 0x0930 /* Toshiba Corp */ +#define USB_VENDOR_INTREPIDCS 0x093c /* Intrepid */ +#define USB_VENDOR_YANO 0x094f /* Yano */ +#define USB_VENDOR_KINGSTON 0x0951 /* Kingston Technology */ +#define USB_VENDOR_NVIDIA 0x0955 /* NVIDIA */ +#define USB_VENDOR_BLUEWATER 0x0956 /* BlueWater Systems */ +#define USB_VENDOR_AGILENT 0x0957 /* Agilent Technologies */ +#define USB_VENDOR_GUDE 0x0959 /* Gude ADS */ +#define USB_VENDOR_PORTSMITH 0x095a /* Portsmith */ +#define USB_VENDOR_ACERW 0x0967 /* Acer */ +#define USB_VENDOR_ADIRONDACK 0x0976 /* Adirondack Wire & Cable */ +#define USB_VENDOR_BECKHOFF 0x0978 /* Beckhoff */ +#define USB_VENDOR_MINDSATWORK 0x097a /* Minds At Work */ +#define USB_VENDOR_INTERSIL 0x09aa /* Intersil */ +#define USB_VENDOR_ALTIUS 0x09b3 /* Altius Solutions */ +#define USB_VENDOR_ARRIS 0x09c1 /* Arris Interactive */ +#define USB_VENDOR_ACTIVCARD 0x09c3 /* ACTIVCARD */ +#define USB_VENDOR_ACTISYS 0x09c4 /* ACTiSYS */ +#define USB_VENDOR_NOVATEL1 0x09d7 /* Novatel */ +#define USB_VENDOR_AFOURTECH 0x09da /* A-FOUR TECH */ +#define USB_VENDOR_AIMEX 0x09dc /* AIMEX */ +#define USB_VENDOR_ADDONICS 0x09df /* Addonics Technologies */ +#define USB_VENDOR_AKAI 0x09e8 /* AKAI professional M.I. */ +#define USB_VENDOR_ARESCOM 0x09f5 /* ARESCOM */ +#define USB_VENDOR_BAY 0x09f9 /* Bay Associates */ +#define USB_VENDOR_ALTERA 0x09fb /* Altera */ +#define USB_VENDOR_CSR 0x0a12 /* Cambridge Silicon Radio */ +#define USB_VENDOR_TREK 0x0a16 /* Trek Technology */ +#define USB_VENDOR_ASAHIOPTICAL 0x0a17 /* Asahi Optical */ +#define USB_VENDOR_BOCASYSTEMS 0x0a43 /* Boca Systems */ +#define USB_VENDOR_SHANTOU 0x0a46 /* ShanTou */ +#define USB_VENDOR_HIROSE 0x0a47 /* Hirose */ +#define USB_VENDOR_BROADCOM 0x0a5c /* Broadcom */ +#define USB_VENDOR_GREENHOUSE 0x0a6b /* GREENHOUSE */ +#define USB_VENDOR_GEOCAST 0x0a79 /* Geocast Network Systems */ +#define USB_VENDOR_DREAMCHEEKY 0x0a81 /* Dream Cheeky */ +#define USB_VENDOR_IDQUANTIQUE 0x0aba /* id Quantique */ +#define USB_VENDOR_IDTECH 0x0acd /* ID TECH */ +#define USB_VENDOR_ZYDAS 0x0ace /* ZyDAS Technology */ +#define USB_VENDOR_CHENSOURCE 0x0ad2 /* Chen-Source */ +#define USB_VENDOR_NEODIO 0x0aec /* Neodio */ +#define USB_VENDOR_OPTION 0x0af0 /* Option */ +#define USB_VENDOR_ASUS 0x0b05 /* ASUS */ +#define USB_VENDOR_TODOS 0x0b0c /* Todos Data System */ +#define USB_VENDOR_GEARHEAD 0x0b38 /* Gear Head */ +#define USB_VENDOR_OCT 0x0b39 /* Omnidirectional Control Technology */ +#define USB_VENDOR_TEKRAM 0x0b3b /* Tekram Technology */ +#define USB_VENDOR_HAL 0x0b41 /* HAL Corporation */ +#define USB_VENDOR_NEC2 0x0b62 /* NEC */ +#define USB_VENDOR_ATI2 0x0b6f /* ATI */ +#define USB_VENDOR_KURUSUGAWA 0x0b7e /* Kurusugawa Electronics */ +#define USB_VENDOR_SMART 0x0b8c /* Smart Technologies */ +#define USB_VENDOR_ASIX 0x0b95 /* ASIX Electronics */ +#define USB_VENDOR_O2MICRO 0x0b97 /* O2 Micro */ +#define USB_VENDOR_SACOM 0x0ba0 /* System SACOM Industry Co.,Ltd */ +#define USB_VENDOR_USR 0x0baf /* U.S. Robotics */ +#define USB_VENDOR_AMBIT 0x0bb2 /* Ambit Microsystems */ +#define USB_VENDOR_HTC 0x0bb4 /* HTC */ +#define USB_VENDOR_REALTEK 0x0bda /* Realtek */ +#define USB_VENDOR_ERICSSON 0x0bdb /* Ericsson */ +#define USB_VENDOR_MEI 0x0bed /* MEI */ +#define USB_VENDOR_ADDONICS2 0x0bf6 /* Addonics Technology */ +#define USB_VENDOR_FSC 0x0bf8 /* Fujitsu Siemens Computers */ +#define USB_VENDOR_AGATE 0x0c08 /* Agate Technologies */ +#define USB_VENDOR_DMI 0x0c0b /* DMI */ +#define USB_VENDOR_ICOM 0x0c26 /* Icom */ +#define USB_VENDOR_GNOTOMETRICS 0x0c33 /* GN Otometrics */ +#define USB_VENDOR_MICRODIA 0x0c45 /* Microdia / Sonix Technology Co., Ltd. */ +#define USB_VENDOR_SEALEVEL 0x0c52 /* Sealevel System */ +#define USB_VENDOR_JETI 0x0c6c /* JETI */ +#define USB_VENDOR_EASYDISK 0x0c76 /* EasyDisk */ +#define USB_VENDOR_ELEKTOR 0x0c7d /* Elektor Electronics */ +#define USB_VENDOR_KYOCERA2 0x0c88 /* Kyocera */ +#define USB_VENDOR_TERRATEC 0x0ccd /* TerraTec Electronic GmbH */ +#define USB_VENDOR_ZCOM 0x0cde /* Z-Com */ +#define USB_VENDOR_ATHEROS2 0x0cf3 /* Atheros Communications */ +#define USB_VENDOR_POSIFLEX 0x0d3a /* Posiflex Technologies */ +#define USB_VENDOR_TANGTOP 0x0d3d /* Tangtop */ +#define USB_VENDOR_KOBIL 0x0d46 /* Kobil Systems */ +#define USB_VENDOR_SMC3 0x0d5c /* SMC */ +#define USB_VENDOR_PEN 0x0d7d /* Pen Drive */ +#define USB_VENDOR_ABC 0x0d8c /* ABC */ +#define USB_VENDOR_CONCEPTRONIC 0x0d8e /* Conceptronic */ +#define USB_VENDOR_MSI 0x0db0 /* Micro Star International */ +#define USB_VENDOR_ELCON 0x0db7 /* ELCON Systemtechnik */ +#define USB_VENDOR_UNKNOWN5 0x0dcd /* Unknown Vendor */ +#define USB_VENDOR_SITECOMEU 0x0df6 /* Sitecom Europe */ +#define USB_VENDOR_MOBILEACTION 0x0df7 /* Mobile Action */ +#define USB_VENDOR_AMIGO 0x0e0b /* Amigo Technology */ +#define USB_VENDOR_VMWARE 0x0e0f /* VMware */ +#define USB_VENDOR_SPEEDDRAGON 0x0e55 /* Speed Dragon Multimedia */ +#define USB_VENDOR_CTC 0x0e5e /* CONWISE Technology */ +#define USB_VENDOR_HAWKING 0x0e66 /* Hawking */ +#define USB_VENDOR_FOSSIL 0x0e67 /* Fossil */ +#define USB_VENDOR_GMATE 0x0e7e /* G.Mate */ +#define USB_VENDOR_MEDIATEK 0x0e8d /* MediaTek Inc. */ +#define USB_VENDOR_OTI 0x0ea0 /* Ours Technology */ +#define USB_VENDOR_PILOTECH 0x0eaf /* Pilotech */ +#define USB_VENDOR_NOVATECH 0x0eb0 /* Nova Tech */ +#define USB_VENDOR_ITEGNO 0x0eba /* iTegno */ +#define USB_VENDOR_NORITAKE 0x0eda /* Noritake itron Corp */ +#define USB_VENDOR_EGALAX 0x0eef /* eGalax */ +#define USB_VENDOR_XIRING 0x0f14 /* XIRING */ +#define USB_VENDOR_IOI 0x0f21 /* IOI */ +#define USB_VENDOR_AIRPRIME 0x0f3d /* Airprime */ +#define USB_VENDOR_VTECH 0x0f88 /* VTech */ +#define USB_VENDOR_FALCOM 0x0f94 /* Falcom Wireless Communications */ +#define USB_VENDOR_RIM 0x0fca /* Research In Motion */ +#define USB_VENDOR_DYNASTREAM 0x0fcf /* Dynastream Innovations */ +#define USB_VENDOR_LARSENBRUSGAARD 0x0fd8 /* Larsen and Brusgaard */ +#define USB_VENDOR_OREGONSCI 0x0fde /* Oregon Scientific */ +#define USB_VENDOR_UNKNOWN4 0x0fe6 /* Unknown Vendor */ +#define USB_VENDOR_DVICO 0x0fe9 /* DViCO */ +#define USB_VENDOR_QUALCOMM2 0x1004 /* Qualcomm */ +#define USB_VENDOR_MOTOROLA4 0x100d /* Motorola */ +#define USB_VENDOR_TTL 0x1025 /* Technology Testing Lab */ +#define USB_VENDOR_HP3 0x103c /* Hewlett Packard */ +#define USB_VENDOR_THURLBY 0x103e /* Thurlby Thandar Instruments */ +#define USB_VENDOR_GIGABYTE 0x1044 /* GIGABYTE */ +#define USB_VENDOR_YUBICO 0x1050 /* Yubico.com */ +#define USB_VENDOR_MOTOROLA 0x1063 /* Motorola */ +#define USB_VENDOR_CCYU 0x1065 /* CCYU Technology */ +#define USB_VENDOR_HYUNDAI 0x106c /* Hyundai */ +#define USB_VENDOR_GCTSEMICON 0x1076 /* GCT Semiconductor */ +#define USB_VENDOR_SILABS2 0x10a6 /* Silicon Labs */ +#define USB_VENDOR_USI 0x10ab /* USI */ +#define USB_VENDOR_LIEBERT2 0x10af /* Liebert */ +#define USB_VENDOR_PLX 0x10b5 /* PLX */ +#define USB_VENDOR_ASANTE 0x10bd /* Asante */ +#define USB_VENDOR_SILABS 0x10c4 /* Silicon Labs */ +#define USB_VENDOR_SILABS3 0x10c5 /* Silicon Labs */ +#define USB_VENDOR_SILABS4 0x10ce /* Silicon Labs */ +#define USB_VENDOR_VELLEMAN 0x10cf /* Velleman */ +#define USB_VENDOR_MOXA 0x110a /* Moxa Technologies */ +#define USB_VENDOR_ANALOG 0x1110 /* Analog Devices */ +#define USB_VENDOR_TENX 0x1130 /* Ten X Technology, Inc. */ +#define USB_VENDOR_ISSC 0x1131 /* Integrated System Solution Corp. */ +#define USB_VENDOR_JRC 0x1145 /* Japan Radio Company */ +#define USB_VENDOR_SPHAIRON 0x114b /* Sphairon Access Systems */ +#define USB_VENDOR_DELORME 0x1163 /* DeLorme */ +#define USB_VENDOR_SERVERWORKS 0x1166 /* ServerWorks */ +#define USB_VENDOR_ACERCM 0x1189 /* Acer Communications & Multimedia */ +#define USB_VENDOR_SIERRA 0x1199 /* Sierra Wireless */ +#define USB_VENDOR_SIEMENS3 0x11f5 /* Siemens */ +#define USB_VENDOR_ALCATEL 0x11f7 /* Alcatel */ +#define USB_VENDOR_INTERBIO 0x1209 /* InterBiometrics */ +#define USB_VENDOR_UNKNOWN3 0x1233 /* Unknown vendor */ +#define USB_VENDOR_TSUNAMI 0x1241 /* Tsunami */ +#define USB_VENDOR_PHEENET 0x124a /* Pheenet */ +#define USB_VENDOR_RAPTORGAMING 0x1267 /* Raptor Gaming */ +#define USB_VENDOR_TWINMOS 0x126f /* TwinMOS */ +#define USB_VENDOR_TENDA 0x1286 /* Tenda */ +#define USB_VENDOR_TESTO 0x128d /* Testo AG */ +#define USB_VENDOR_CREATIVE2 0x1292 /* Creative Labs */ +#define USB_VENDOR_BELKIN2 0x1293 /* Belkin Components */ +#define USB_VENDOR_CYBERTAN 0x129b /* CyberTAN Technology */ +#define USB_VENDOR_HUAWEI 0x12d1 /* HUAWEI Technologies */ +#define USB_VENDOR_ARANEUS 0x12d8 /* Araneus Information Systems */ +#define USB_VENDOR_TAPWAVE 0x12ef /* Tapwave */ +#define USB_VENDOR_AINCOMM 0x12fd /* Aincomm */ +#define USB_VENDOR_MOBILITY 0x1342 /* Mobility */ +#define USB_VENDOR_DICKSMITH 0x1371 /* Dick Smith Electronics */ +#define USB_VENDOR_NETGEAR3 0x1385 /* Netgear */ +#define USB_VENDOR_VALIDITY 0x138a /* Validity Sensors */ +#define USB_VENDOR_BALTECH 0x13ad /* Baltech */ +#define USB_VENDOR_CISCOLINKSYS 0x13b1 /* Cisco-Linksys */ +#define USB_VENDOR_SHARK 0x13d2 /* Shark */ +#define USB_VENDOR_AZUREWAVE 0x13d3 /* AsureWave */ +#define USB_VENDOR_NOVATEL 0x1410 /* Novatel */ +#define USB_VENDOR_WISTRONNEWEB 0x1435 /* Wistron NeWeb */ +#define USB_VENDOR_RADIOSHACK 0x1453 /* Radio Shack */ +#define USB_VENDOR_OPENMOKO 0x1457 /* OpenMoko */ +#define USB_VENDOR_HUAWEI3COM 0x1472 /* Huawei 3Com */ +#define USB_VENDOR_ABOCOM2 0x1482 /* AboCom Systems */ +#define USB_VENDOR_SILICOM 0x1485 /* Silicom */ +#define USB_VENDOR_RALINK 0x148f /* Ralink Technology */ +#define USB_VENDOR_STARTECH 0x14b0 /* StarTech.com */ +#define USB_VENDOR_CONCEPTRONIC2 0x14b2 /* Conceptronic */ +#define USB_VENDOR_SUPERTOP 0x14cd /* SuperTop */ +#define USB_VENDOR_PLANEX3 0x14ea /* Planex Communications */ +#define USB_VENDOR_TWINHEAD 0x14ff /* Twinhead */ +#define USB_VENDOR_SILICONPORTALS 0x1527 /* Silicon Portals */ +#define USB_VENDOR_UBLOX 0x1546 /* U-blox */ +#define USB_VENDOR_OWEN 0x1555 /* Owen */ +#define USB_VENDOR_OQO 0x1557 /* OQO */ +#define USB_VENDOR_UMEDIA 0x157e /* U-MEDIA Communications */ +#define USB_VENDOR_FIBERLINE 0x1582 /* Fiberline */ +#define USB_VENDOR_SPARKLAN 0x15a9 /* SparkLAN */ +#define USB_VENDOR_OLIMEX 0x15ba /* Olimex */ +#define USB_VENDOR_AMIT2 0x15c5 /* AMIT */ +#define USB_VENDOR_TRUST 0x15d9 /* Trust */ +#define USB_VENDOR_SOHOWARE 0x15e8 /* SOHOware */ +#define USB_VENDOR_UMAX 0x1606 /* UMAX Data Systems */ +#define USB_VENDOR_INSIDEOUT 0x1608 /* Inside Out Networks */ +#define USB_VENDOR_GOODWAY 0x1631 /* Good Way Technology */ +#define USB_VENDOR_ENTREGA 0x1645 /* Entrega */ +#define USB_VENDOR_ACTIONTEC 0x1668 /* Actiontec Electronics */ +#define USB_VENDOR_CLIPSAL 0x166a /* Clipsal */ +#define USB_VENDOR_CISCOLINKSYS2 0x167b /* Cisco-Linksys */ +#define USB_VENDOR_ATHEROS 0x168c /* Atheros Communications */ +#define USB_VENDOR_GIGASET 0x1690 /* Gigaset */ +#define USB_VENDOR_GLOBALSUN 0x16ab /* Global Sun Technology */ +#define USB_VENDOR_VOTI 0x16c0 /* Van Ooijen Technische Informatica */ +#define USB_VENDOR_ANYDATA 0x16d5 /* AnyDATA Inc. */ +#define USB_VENDOR_JABLOTRON 0x16d6 /* Jablotron */ +#define USB_VENDOR_CMOTECH 0x16d8 /* CMOTECH */ +#define USB_VENDOR_WIENERPLEINBAUS 0x16dc /* WIENER Plein & Baus */ +#define USB_VENDOR_AXESSTEL 0x1726 /* Axesstel */ +#define USB_VENDOR_LINKSYS4 0x1737 /* Linksys */ +#define USB_VENDOR_SENAO 0x1740 /* Senao */ +#define USB_VENDOR_ASUS2 0x1761 /* ASUS */ +#define USB_VENDOR_STRAWBERRYLINUX 0x1774 /* Strawberry linux Co., Ltd. */ +#define USB_VENDOR_SWEEX2 0x177f /* Sweex */ +#define USB_VENDOR_MECANIQUE 0x1781 /* Mecanique */ +#define USB_VENDOR_KAMSTRUP 0x17a8 /* Kamstrup A/S */ +#define USB_VENDOR_DISPLAYLINK 0x17e9 /* DisplayLink */ +#define USB_VENDOR_LENOVO 0x17ef /* Lenovo */ +#define USB_VENDOR_WAVESENSE 0x17f4 /* WaveSense */ +#define USB_VENDOR_VAISALA 0x1843 /* VAISALA */ +#define USB_VENDOR_AMIT 0x18c5 /* AMIT */ +#define USB_VENDOR_GOOGLE 0x18d1 /* Google */ +#define USB_VENDOR_QCOM 0x18e8 /* Qcom */ +#define USB_VENDOR_ELV 0x18ef /* ELV */ +#define USB_VENDOR_LINKSYS3 0x1915 /* Linksys */ +#define USB_VENDOR_AVAGO 0x192f /* Avago */ +#define USB_VENDOR_MEINBERG 0x1938 /* Meinberg Funkuhren */ +#define USB_VENDOR_ZTE 0x19d2 /* ZTE Inc. */ +#define USB_VENDOR_QUANTA 0x1a32 /* Quanta */ +#define USB_VENDOR_TERMINUS 0x1a40 /* Terminus Technology */ +#define USB_VENDOR_ABBOTT 0x1a61 /* Abbott Labs */ +#define USB_VENDOR_BAYER 0x1a79 /* Bayer Health Care */ +#define USB_VENDOR_WCH2 0x1a86 /* QinHeng Electronics */ +#define USB_VENDOR_SEL 0x1adb /* Schweitzer Engineering Laboratories */ +#define USB_VENDOR_CORSAIR 0x1b1c /* Corsair */ +#define USB_VENDOR_MATRIXORB 0x1b3d /* Matrix Orbital */ +#define USB_VENDOR_TORADEX 0x1b67 /* Toradex inc. */ +#define USB_VENDOR_FUSHICAI 0x1b71 /* Fushicai */ +#define USB_VENDOR_OVISLINK 0x1b75 /* OvisLink */ +#define USB_VENDOR_TML 0x1b91 /* The Mobility Lab */ +#define USB_VENDOR_SILABS5 0x1ba4 /* Silicon Labs */ +#define USB_VENDOR_TCTMOBILE 0x1bbb /* TCT Mobile */ +#define USB_VENDOR_MDS 0x1bc8 /* MDS */ +#define USB_VENDOR_ALTI2 0x1bc9 /* Alti-2 */ +#define USB_VENDOR_SUNPLUS 0x1bcf /* Sunplus */ +#define USB_VENDOR_WAGO 0x1be3 /* WAGO Kontakttechnik */ +#define USB_VENDOR_QNAP 0x1c04 /* QNAP */ +#define USB_VENDOR_LONGCHEER 0x1c9e /* Longcheer Technology */ +#define USB_VENDOR_DRESDENELEC 0x1cf1 /* Dresden Elektronic */ +#define USB_VENDOR_DREAMLINK 0x1d34 /* Dream Link */ +#define USB_VENDOR_PEGATRON 0x1d4d /* Pegatron */ +#define USB_VENDOR_OPENMOKO2 0x1d50 /* OpenMoko */ +#define USB_VENDOR_SELUXIT 0x1d6f /* Seluxit */ +#define USB_VENDOR_METAGEEK 0x1dd5 /* MetaGeek */ +#define USB_VENDOR_SIMCOM 0x1e0e /* SIMCom Wireless Solutions Co., Ltd. */ +#define USB_VENDOR_FESTO 0x1e29 /* Festo */ +#define USB_VENDOR_MODACOM 0x1eb8 /* Modacom */ +#define USB_VENDOR_AIRTIES 0x1eda /* AirTies */ +#define USB_VENDOR_LAKESHORE 0x1fb9 /* Lake Shore */ +#define USB_VENDOR_VERTEX 0x1fe7 /* Vertex Wireless Co., Ltd. */ +#define USB_VENDOR_DLINK 0x2001 /* D-Link */ +#define USB_VENDOR_PLANEX2 0x2019 /* Planex Communications */ +#define USB_VENDOR_ENCORE 0x203d /* Encore */ +#define USB_VENDOR_LUXSHARE 0x208e /* Luxshare */ +#define USB_VENDOR_PARA 0x20b8 /* PARA Industrial */ +#define USB_VENDOR_TRENDNET 0x20f4 /* TRENDnet */ +#define USB_VENDOR_RTSYSTEMS 0x2100 /* RT Systems */ +#define USB_VENDOR_DLINK3 0x2101 /* D-Link */ +#define USB_VENDOR_VIALABS 0x2109 /* VIA Labs */ +#define USB_VENDOR_MOTOROLA2 0x22b8 /* Motorola */ +#define USB_VENDOR_ARDUINO 0x2341 /* Arduino SA */ +#define USB_VENDOR_TPLINK 0x2357 /* TP-Link */ +#define USB_VENDOR_WMR 0x2405 /* West Mountain Radio */ +#define USB_VENDOR_TRIPPLITE 0x2478 /* Tripp-Lite */ +#define USB_VENDOR_HAILUCK 0x258a /* HAILUCK Co., Ltd */ +#define USB_VENDOR_ARUBA 0x2626 /* Aruba */ +#define USB_VENDOR_XIAOMI 0x2717 /* Xiaomi */ +#define USB_VENDOR_NHJ 0x2770 /* NHJ */ +#define USB_VENDOR_THINGM 0x27b8 /* ThingM */ +#define USB_VENDOR_ASUSTEK 0x2821 /* ASUSTeK Computer */ +#define USB_VENDOR_PIONEERDJ 0x2b73 /* Pioneer DJ */ +#define USB_VENDOR_PLANEX 0x2c02 /* Planex Communications */ +#define USB_VENDOR_QUECTEL 0x2c7c /* Quectel */ +#define USB_VENDOR_CLUB3D 0x2d1c /* Club 3D */ +#define USB_VENDOR_AQUANTIA 0x2eca /* Aquantia */ +#define USB_VENDOR_CLEVO 0x30da /* CLEVO */ +#define USB_VENDOR_DYNABOOK 0x30f3 /* Dynabook */ +#define USB_VENDOR_LINKINSTRUMENTS 0x3195 /* Link Instruments */ +#define USB_VENDOR_AEI 0x3334 /* AEI */ +#define USB_VENDOR_PQI 0x3538 /* PQI */ +#define USB_VENDOR_DAISY 0x3579 /* Daisy Technology */ +#define USB_VENDOR_NI 0x3923 /* National Instruments */ +#define USB_VENDOR_MICRONET 0x3980 /* Micronet Communications */ +#define USB_VENDOR_IODATA2 0x40bb /* I-O Data */ +#define USB_VENDOR_IRIVER 0x4102 /* iRiver */ +#define USB_VENDOR_DELL 0x413c /* Dell */ +#define USB_VENDOR_PCSENSORS 0x413d /* PC Sensors */ +#define USB_VENDOR_WCH 0x4348 /* QinHeng Electronics */ +#define USB_VENDOR_ACEECA 0x4766 /* Aceeca */ +#define USB_VENDOR_FEIXUN 0x4855 /* FeiXun Communication */ +#define USB_VENDOR_NETWEEN 0x4856 /* NetweeN */ +#define USB_VENDOR_PAPOUCH 0x5050 /* Papouch s.r.o. */ +#define USB_VENDOR_AVERATEC 0x50c2 /* Averatec */ +#define USB_VENDOR_SWEEX 0x5173 /* Sweex */ +#define USB_VENDOR_PROLIFIC2 0x5372 /* Prolific Technology */ +#define USB_VENDOR_ONSPEC2 0x55aa /* OnSpec */ +#define USB_VENDOR_ACERLABS2 0x5986 /* Acer */ +#define USB_VENDOR_ZINWELL 0x5a57 /* Zinwell */ +#define USB_VENDOR_SITECOM 0x6189 /* Sitecom */ +#define USB_VENDOR_ARKMICRO 0x6547 /* Arkmicro */ +#define USB_VENDOR_3COM2 0x6891 /* 3Com */ +#define USB_VENDOR_EDIMAX 0x7392 /* EDIMAX */ +#define USB_VENDOR_INTEL 0x8086 /* Intel */ +#define USB_VENDOR_INTEL2 0x8087 /* Intel */ +#define USB_VENDOR_ALLWIN 0x8516 /* ALLWIN Tech */ +#define USB_VENDOR_SITECOM2 0x9016 /* Sitecom */ +#define USB_VENDOR_MOSCHIP 0x9710 /* MosChip */ +#define USB_VENDOR_NETGEAR4 0x9846 /* Netgear */ +#define USB_VENDOR_MARVELL 0x9e88 /* Marvell */ +#define USB_VENDOR_3COM3 0xa727 /* 3Com */ +#define USB_VENDOR_CACE 0xcace /* CACE Technologies */ +#define USB_VENDOR_COMPARE 0xcdab /* Compare */ +#define USB_VENDOR_DATAAPEX 0xdaae /* DataApex */ +#define USB_VENDOR_EVOLUTION 0xdeee /* Evolution Robotics */ +#define USB_VENDOR_EMPIA 0xeb1a /* eMPIA Technology */ +#define USB_VENDOR_HP2 0xf003 /* Hewlett Packard */ + +/* + * List of known products. Grouped by vendor. + */ + +/* 3Com products */ +#define USB_PRODUCT_3COM_HOMECONN 0x009d /* HomeConnect */ +#define USB_PRODUCT_3COM_3CREB96 0x00a0 /* Bluetooth */ +#define USB_PRODUCT_3COM_3C19250 0x03e8 /* 3C19250 Ethernet */ +#define USB_PRODUCT_3COM_3CRSHEW696 0x0a01 /* 3CRSHEW696 */ +#define USB_PRODUCT_3COM_3C460 0x11f8 /* HomeConnect 3C460 */ +#define USB_PRODUCT_3COM_USR56K 0x3021 /* U.S.Robotics 56000 */ +#define USB_PRODUCT_3COM_3C460B 0x4601 /* HomeConnect 3C460B */ + +/* 3Com(2) products */ +#define USB_PRODUCT_3COM2_3CRUSB10075 0xa727 /* 3CRUSB10075 */ + +/* 3Com(3) products */ +#define USB_PRODUCT_3COM3_AR5523_1 0x6893 /* AR5523 */ +#define USB_PRODUCT_3COM3_AR5523_2 0x6895 /* AR5523 */ +#define USB_PRODUCT_3COM3_AR5523_3 0x6897 /* AR5523 */ + +#define USB_PRODUCT_3COMUSR_OFFICECONN 0x0082 /* 3Com OfficeConnect Analog Modem */ +#define USB_PRODUCT_3COMUSR_USRISDN 0x008f /* 3Com U.S. Robotics Pro ISDN TA */ +#define USB_PRODUCT_3COMUSR_HOMECONN 0x009d /* 3Com HomeConnect */ +#define USB_PRODUCT_3COMUSR_USR56K 0x3021 /* U.S.Robotics 56000 */ + +/* Abbott products */ +#define USB_PRODUCT_ABBOTT_STEREO_PLUG 0x3410 /* Stereo Plug Cable */ + +/* AboCom products */ +#define USB_PRODUCT_ABOCOM_XX1 0x110c /* XX1 */ +#define USB_PRODUCT_ABOCOM_XX2 0x200c /* XX2 */ +#define USB_PRODUCT_ABOCOM_RT2770 0x2770 /* RT2770 */ +#define USB_PRODUCT_ABOCOM_RT2870 0x2870 /* RT2870 */ +#define USB_PRODUCT_ABOCOM_RT3070 0x3070 /* RT3070 */ +#define USB_PRODUCT_ABOCOM_RT3071 0x3071 /* RT3071 */ +#define USB_PRODUCT_ABOCOM_RT3072 0x3072 /* RT3072 */ +#define USB_PRODUCT_ABOCOM_URE450 0x4000 /* URE450 Ethernet */ +#define USB_PRODUCT_ABOCOM_UFE1000 0x4002 /* UFE1000 Fast Ethernet */ +#define USB_PRODUCT_ABOCOM_DSB650TX_PNA 0x4003 /* 1/10/100 Ethernet */ +#define USB_PRODUCT_ABOCOM_XX4 0x4004 /* XX4 */ +#define USB_PRODUCT_ABOCOM_XX5 0x4007 /* XX5 */ +#define USB_PRODUCT_ABOCOM_XX6 0x400b /* XX6 */ +#define USB_PRODUCT_ABOCOM_XX7 0x400c /* XX7 */ +#define USB_PRODUCT_ABOCOM_LCS8138TX 0x401a /* LCS-8138TX */ +#define USB_PRODUCT_ABOCOM_XX8 0x4102 /* XX8 */ +#define USB_PRODUCT_ABOCOM_XX9 0x4104 /* XX9 */ +#define USB_PRODUCT_ABOCOM_UF200 0x420a /* UF200 Ethernet */ +#define USB_PRODUCT_ABOCOM_WL54 0x6001 /* WL54 */ +#define USB_PRODUCT_ABOCOM_RTL8192CU 0x8178 /* RTL8192CU */ +#define USB_PRODUCT_ABOCOM_RTL8188EU 0x8179 /* RTL8188EU */ +#define USB_PRODUCT_ABOCOM_RTL8188CU_1 0x8188 /* RTL8188CU */ +#define USB_PRODUCT_ABOCOM_RTL8188CU_2 0x8189 /* RTL8188CU */ +#define USB_PRODUCT_ABOCOM_XX10 0xabc1 /* XX10 */ +#define USB_PRODUCT_ABOCOM_BWU613 0xb000 /* BWU613 */ +#define USB_PRODUCT_ABOCOM_HWU54DM 0xb21b /* HWU54DM */ +#define USB_PRODUCT_ABOCOM_RT2573_2 0xb21c /* RT2573 */ +#define USB_PRODUCT_ABOCOM_RT2573_3 0xb21d /* RT2573 */ +#define USB_PRODUCT_ABOCOM_RT2573_4 0xb21e /* RT2573 */ +#define USB_PRODUCT_ABOCOM_WUG2700 0xb21f /* WUG2700 */ +#define USB_PRODUCT_ABOCOM2_RT2870_1 0x3c09 /* RT2870 */ + +/* Accton products */ +#define USB_PRODUCT_ACCTON_USB320_EC 0x1046 /* USB320-EC Ethernet */ +#define USB_PRODUCT_ACCTON_2664W 0x3501 /* 2664W */ +#define USB_PRODUCT_ACCTON_111 0x3503 /* T-Sinus 111 WLAN */ +#define USB_PRODUCT_ACCTON_SMCWUSBG 0x4505 /* SMCWUSB-G */ +#define USB_PRODUCT_ACCTON_SMCWUSBTG2 0x4506 /* SMCWUSBT-G2 */ +#define USB_PRODUCT_ACCTON_SMCWUSBTG2_NF 0x4507 /* SMCWUSBT-G2 */ +#define USB_PRODUCT_ACCTON_PRISM_GT 0x4521 /* PrismGT USB 2.0 WLAN */ +#define USB_PRODUCT_ACCTON_SS1001 0x5046 /* SpeedStream Ethernet */ +#define USB_PRODUCT_ACCTON_RT2870_2 0x6618 /* RT2870 */ +#define USB_PRODUCT_ACCTON_RT3070 0x7511 /* RT3070 */ +#define USB_PRODUCT_ACCTON_RT2770 0x7512 /* RT2770 */ +#define USB_PRODUCT_ACCTON_RT2870_3 0x7522 /* RT2870 */ +#define USB_PRODUCT_ACCTON_RT2870_5 0x8522 /* RT2870 */ +#define USB_PRODUCT_ACCTON_RT3070_4 0xa512 /* RT3070 */ +#define USB_PRODUCT_ACCTON_RT2870_4 0xa618 /* RT2870 */ +#define USB_PRODUCT_ACCTON_RT3070_1 0xa701 /* RT3070 */ +#define USB_PRODUCT_ACCTON_RT3070_2 0xa702 /* RT3070 */ +#define USB_PRODUCT_ACCTON_RT3070_6 0xa703 /* RT3070 */ +#define USB_PRODUCT_ACCTON_AR9280 0xa704 /* AR9280+AR7010 */ +#define USB_PRODUCT_ACCTON_RT2870_1 0xb522 /* RT2870 */ +#define USB_PRODUCT_ACCTON_RTL8192SU 0xc512 /* RTL8192SU */ +#define USB_PRODUCT_ACCTON_RT3070_3 0xc522 /* RT3070 */ +#define USB_PRODUCT_ACCTON_RT3070_5 0xd522 /* RT3070 */ +#define USB_PRODUCT_ACCTON_ZD1211B 0xe501 /* ZD1211B */ +#define USB_PRODUCT_ACCTON_WN4501H_LF_IR 0xe503 /* WN4501H-LF-IR */ +#define USB_PRODUCT_ACCTON_WUS201 0xe506 /* WUS-201 */ +#define USB_PRODUCT_ACCTON_WN7512 0xf522 /* WN7512 */ + +/* Aceeca products */ +#define USB_PRODUCT_ACEECA_MEZ1000 0x0001 /* MEZ1000 RDA */ + +/* Acer Communications & Multimedia products */ +#define USB_PRODUCT_ACERCM_EP1427X2 0x0893 /* EP-1427X-2 Ethernet */ + +/* Acer Labs products */ +#define USB_PRODUCT_ACERLABS_M5632 0x5632 /* USB 2.0 Data Link */ + +/* Acer Peripherals, Inc. products */ +#define USB_PRODUCT_ACERP_ACERSCAN_C310U 0x12a6 /* Acerscan C310U */ +#define USB_PRODUCT_ACERP_ACERSCAN_320U 0x2022 /* Acerscan 320U */ +#define USB_PRODUCT_ACERP_ACERSCAN_640U 0x2040 /* Acerscan 640U */ +#define USB_PRODUCT_ACERP_ACERSCAN_620U 0x2060 /* Acerscan 620U */ +#define USB_PRODUCT_ACERP_ATAPI 0x6003 /* ATA/ATAPI */ +#define USB_PRODUCT_ACERP_AWL300 0x9000 /* AWL300 */ +#define USB_PRODUCT_ACERP_AWL400 0x9001 /* AWL400 */ + +/* Acer Products */ +#define USB_PRODUCT_ACERW_WARPLINK 0x0204 /* Warplink */ + +/* Actiontec products */ +#define USB_PRODUCT_ACTIONTEC_PRISM_25 0x0408 /* Prism2.5 WLAN */ +#define USB_PRODUCT_ACTIONTEC_PRISM_25A 0x0421 /* Prism2.5 WLAN A */ +#define USB_PRODUCT_ACTIONTEC_AR9287 0x1200 /* AR9287+AR7010 */ +#define USB_PRODUCT_ACTIONTEC_FREELAN 0x6106 /* ROPEX FreeLan 802.11b */ +#define USB_PRODUCT_ACTIONTEC_802UAT1 0x7605 /* 802UAT1 */ + +/* ACTiSYS products */ +#define USB_PRODUCT_ACTISYS_IR2000U 0x0011 /* ACT-IR2000U FIR */ + +/* ActiveWire, Inc. products */ +#define USB_PRODUCT_ACTIVEWIRE_IOBOARD 0x0100 /* I/O Board */ +#define USB_PRODUCT_ACTIVEWIRE_IOBOARD_FW1 0x0101 /* I/O Board, rev. 1 */ + +/* Adaptec products */ +#define USB_PRODUCT_ADAPTEC_AWN8020 0x0020 /* AWN-8020 WLAN */ + +/* Addonics products */ +#define USB_PRODUCT_ADDONICS2_205 0xa001 /* Cable 205 */ + +/* Addtron products */ +#define USB_PRODUCT_ADDTRON_AWU120 0xff31 /* AWU-120 */ + +/* ADMtek products */ +#define USB_PRODUCT_ADMTEK_PEGASUSII_4 0x07c2 /* AN986A Ethernet */ +#define USB_PRODUCT_ADMTEK_PEGASUS 0x0986 /* AN986 Ethernet */ +#define USB_PRODUCT_ADMTEK_PEGASUSII 0x8511 /* AN8511 Ethernet */ +#define USB_PRODUCT_ADMTEK_PEGASUSII_2 0x8513 /* AN8513 Ethernet */ +#define USB_PRODUCT_ADMTEK_PEGASUSII_3 0x8515 /* AN8515 Ethernet */ + +/* ADS products */ +#define USB_PRODUCT_ADS_UBS10BT 0x0008 /* UBS-10BT Ethernet */ +#define USB_PRODUCT_ADS_UBS10BTX 0x0009 /* UBS-10BT Ethernet */ + +/* AEI products */ +#define USB_PRODUCT_AEI_FASTETHERNET 0x1701 /* Fast Ethernet */ + +/* Agate Technologies products */ +#define USB_PRODUCT_AGATE_QDRIVE 0x0378 /* Q-Drive */ + +/* AGFA products */ +#define USB_PRODUCT_AGFA_SNAPSCAN1212U 0x0001 /* SnapScan 1212U */ +#define USB_PRODUCT_AGFA_SNAPSCAN1236U 0x0002 /* SnapScan 1236U */ +#define USB_PRODUCT_AGFA_SNAPSCANTOUCH 0x0100 /* SnapScan Touch */ +#define USB_PRODUCT_AGFA_SNAPSCAN1212U2 0x2061 /* SnapScan 1212U */ +#define USB_PRODUCT_AGFA_SNAPSCANE40 0x208d /* SnapScan e40 */ +#define USB_PRODUCT_AGFA_SNAPSCANE50 0x208f /* SnapScan e50 */ +#define USB_PRODUCT_AGFA_SNAPSCANE20 0x2091 /* SnapScan e20 */ +#define USB_PRODUCT_AGFA_SNAPSCANE25 0x2095 /* SnapScan e25 */ +#define USB_PRODUCT_AGFA_SNAPSCANE26 0x2097 /* SnapScan e26 */ +#define USB_PRODUCT_AGFA_SNAPSCANE52 0x20fd /* SnapScan e52 */ + +/* Aincomm products */ +#define USB_PRODUCT_AINCOMM_AWU2000B 0x1001 /* AWU2000B */ + +/* Airprime, Inc. products */ +#define USB_PRODUCT_AIRPRIME_PC5220 0x0112 /* CDMA Wireless EVDO card */ +#define USB_PRODUCT_AIRPRIME_AIRCARD_313U 0x68aa /* Aircard 313U */ + +/* AirTies products */ +#define USB_PRODUCT_AIRTIES_RT3070_2 0x2012 /* RT3070 */ +#define USB_PRODUCT_AIRTIES_RT3070 0x2310 /* RT3070 */ + +/* AKS products */ +#define USB_PRODUCT_AKS_USBHASP 0x0001 /* USB-HASP 0.06 */ + +/* Alcatel products */ +#define USB_PRODUCT_ALCATEL_OT535 0x02df /* One Touch 535/735 */ + +/* Alcatel Telecom products */ +#define USB_PRODUCT_ALCATELT_ST120G 0x0120 /* SpeedTouch 120g */ +#define USB_PRODUCT_ALCATELT_ST121G 0x0121 /* SpeedTouch 121g */ + +/* Alcor Micro, Inc. products */ +#define USB_PRODUCT_ALCOR_MA_KBD_HUB 0x9213 /* MacAlly Kbd Hub */ +#define USB_PRODUCT_ALCOR_AU9814 0x9215 /* AU9814 Hub */ +#define USB_PRODUCT_ALCOR_SM_KBD 0x9410 /* MicroConnectors/StrongMan */ +#define USB_PRODUCT_ALCOR_NEC_KBD_HUB 0x9472 /* NEC Kbd Hub */ + +/* Alcor Micro, Inc.(2) products */ +#define USB_PRODUCT_ALCOR2_KBD_HUB 0x2802 /* Kbd Hub */ + +/* Allied Telesyn International products */ +#define USB_PRODUCT_ALLIEDTELESYN_ATUSB100 0xb100 /* AT-USB100 */ + +/* ALLWIN Tech products */ +#define USB_PRODUCT_ALLWIN_RT2070 0x2070 /* RT2070 */ +#define USB_PRODUCT_ALLWIN_RT2770 0x2770 /* RT2770 */ +#define USB_PRODUCT_ALLWIN_RT2870 0x2870 /* RT2870 */ +#define USB_PRODUCT_ALLWIN_RT3070 0x3070 /* RT3070 */ +#define USB_PRODUCT_ALLWIN_RT3071 0x3071 /* RT3071 */ +#define USB_PRODUCT_ALLWIN_RT3072 0x3072 /* RT3072 */ +#define USB_PRODUCT_ALLWIN_RT3572 0x3572 /* RT3572 */ + +/* Altec Lansing products */ +#define USB_PRODUCT_ALTEC_ADA70 0x0070 /* ADA70 Speakers */ +#define USB_PRODUCT_ALTEC_ASC495 0xff05 /* ASC495 Speakers */ + +/* Alti-2 products */ +#define USB_PRODUCT_ALTI2_NEPTUNE3 0x6001 /* Neptune 3 */ + +/* Ambit Microsystems products */ +#define USB_PRODUCT_AMBIT_WLAN 0x0302 /* WLAN */ +#define USB_PRODUCT_AMBIT_NTL_250 0x6098 /* NTL 250 cable modem */ + +/* Advanced Micro Devices products */ +#define USB_PRODUCT_AMD_HUB 0x7900 /* Hub */ + +/* Amigo Technology products */ +#define USB_PRODUCT_AMIGO_RT2870_1 0x9031 /* RT2870 */ +#define USB_PRODUCT_AMIGO_RT2870_2 0x9041 /* RT2870 */ + +/* AMIT products */ +#define USB_PRODUCT_AMIT_CGWLUSB2GO 0x0002 /* CG-WLUSB2GO */ +#define USB_PRODUCT_AMIT_CGWLUSB2GNR 0x0008 /* CG-WLUSB2GNR */ +#define USB_PRODUCT_AMIT_RT2870_1 0x0012 /* RT2870 */ + +/* AMIT(2) products */ +#define USB_PRODUCT_AMIT2_RT2870 0x0008 /* RT2870 */ + +/* Analog Devices, Inc. products */ +#define USB_PRODUCT_ANALOG_EAGLEI 0x900f /* Eagle I */ +#define USB_PRODUCT_ANALOG_EAGLEI_NF 0x9010 /* Eagle I */ +#define USB_PRODUCT_ANALOG_EAGLEII 0x9021 /* Eagle II */ +#define USB_PRODUCT_ANALOG_EAGLEII_NF 0x9022 /* Eagle II */ +#define USB_PRODUCT_ANALOG_EAGLEIIC 0x9023 /* Eagle IIC */ +#define USB_PRODUCT_ANALOG_EAGLEIIC_NF 0x9024 /* Eagle IIC */ +#define USB_PRODUCT_ANALOG_EAGLEIII 0x9031 /* Eagle III */ +#define USB_PRODUCT_ANALOG_EAGLEIII_NF 0x9032 /* Eagle III */ +#define USB_PRODUCT_ANALOGDEVICES_GNICE 0xf000 /* gnICE */ +#define USB_PRODUCT_ANALOGDEVICES_GNICEPLUS 0xf001 /* gnICE+ */ + +/* Anchor products */ +#define USB_PRODUCT_ANCHOR_SERIAL 0x2008 /* Serial */ +#define USB_PRODUCT_ANCHOR_EZUSB 0x2131 /* EZUSB */ +#define USB_PRODUCT_ANCHOR_EZLINK 0x2720 /* EZLINK */ + +/* Anydata products */ +#define USB_PRODUCT_ANYDATA_A2502 0x6202 /* NTT DoCoMo A2502 */ +#define USB_PRODUCT_ANYDATA_ADU_E100H 0x6501 /* ADU-E100H */ +#define USB_PRODUCT_ANYDATA_ADU_500A 0x6502 /* ADU-500A */ + +/* AOX, Inc. products */ +#define USB_PRODUCT_AOX_USB101 0x0008 /* Ethernet */ + +/* American Power Conversion products */ +#define USB_PRODUCT_APC_UPS 0x0002 /* UPS */ +#define USB_PRODUCT_APC_UPS5G 0x0003 /* 5G UPS */ + +/* Apple Computer products */ +#define USB_PRODUCT_APPLE_FOUNTAIN_ANSI 0x020e /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_FOUNTAIN_ISO 0x020f /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_GEYSER_ANSI 0x0214 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_GEYSER_ISO 0x0215 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_GEYSER_JIS 0x0216 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_GEYSER3_ANSI 0x0217 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_GEYSER3_ISO 0x0218 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_GEYSER3_JIS 0x0219 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_GEYSER4_ANSI 0x021a /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_GEYSER4_ISO 0x021b /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_GEYSER4_JIS 0x021c /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING_ANSI 0x0223 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING_ISO 0x0224 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING_JIS 0x0225 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING2_ANSI 0x0230 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING2_ISO 0x0231 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING2_JIS 0x0232 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING3_ANSI 0x0236 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING3_ISO 0x0237 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING3_JIS 0x0238 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING4_ANSI 0x023f /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING4_ISO 0x0240 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING4_JIS 0x0241 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING4A_ANSI 0x0242 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING4A_ISO 0x0243 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING4A_JIS 0x0244 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING5_ANSI 0x0245 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING5_ISO 0x0246 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING5_JIS 0x0247 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING6A_ANSI 0x0249 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING6A_ISO 0x024a /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING6A_JIS 0x024b /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING6_ANSI 0x024c /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING6_ISO 0x024d /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING6_JIS 0x024e /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING5A_ANSI 0x0252 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING5A_ISO 0x0253 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING5A_JIS 0x0254 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING7A_ANSI 0x0259 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING7A_ISO 0x025a /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING7A_JIS 0x025b /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING7_ANSI 0x0262 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING7_ISO 0x0263 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING7_JIS 0x0264 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING9_ANSI 0x0272 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING9_ISO 0x0273 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING9_JIS 0x0274 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING8_ANSI 0x0290 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING8_ISO 0x0291 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING8_JIS 0x0292 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRINGM1_J293 0x0341 /* Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_OPTMOUSE 0x0302 /* Optical mouse */ +#define USB_PRODUCT_APPLE_BLUETOOTH_HCI 0x1000 /* HID-proxy */ +#define USB_PRODUCT_APPLE_SPEAKERS 0x1101 /* Speakers */ +#define USB_PRODUCT_APPLE_IPHONE 0x1290 /* iPhone */ +#define USB_PRODUCT_APPLE_IPOD_TOUCH 0x1291 /* iPod Touch */ +#define USB_PRODUCT_APPLE_IPHONE_3G 0x1292 /* iPhone 3G */ +#define USB_PRODUCT_APPLE_IPOD_TOUCH_2G 0x1293 /* iPod Touch 2G */ +#define USB_PRODUCT_APPLE_IPHONE_3GS 0x1294 /* iPhone 3GS */ +#define USB_PRODUCT_APPLE_IPHONE_4_GSM 0x1297 /* iPhone 4 GSM */ +#define USB_PRODUCT_APPLE_IPOD_TOUCH_3G 0x1299 /* iPod Touch 3G */ +#define USB_PRODUCT_APPLE_IPAD 0x129a /* iPad */ +#define USB_PRODUCT_APPLE_IPHONE_4_CDMA 0x129c /* iPhone 4 CDMA */ +#define USB_PRODUCT_APPLE_IPOD_TOUCH_4G 0x129e /* iPod Touch 4G */ +#define USB_PRODUCT_APPLE_IPAD2 0x129f /* iPad 2 */ +#define USB_PRODUCT_APPLE_IPHONE_4S 0x12a0 /* iPhone 4S */ +#define USB_PRODUCT_APPLE_IPHONE_6 0x12a8 /* iPhone 6 */ +#define USB_PRODUCT_APPLE_ETHERNET 0x1402 /* Ethernet A1277 */ +#define USB_PRODUCT_APPLE_BLUETOOTH2 0x8205 /* Bluetooth */ +#define USB_PRODUCT_APPLE_BLUETOOTH 0x8300 /* Bluetooth */ +#define USB_PRODUCT_APPLE_ISIGHT_1 0x8501 /* iSight */ +#define USB_PRODUCT_APPLE_ISIGHT 0x8502 /* iSight */ + +/* Aquantia products */ +#define USB_PRODUCT_AQUANTIA_AQC111 0xc101 /* AQC111 */ + +/* Araneus Information Systems products */ +#define USB_PRODUCT_ARANEUS_ALEA 0x0001 /* True Random Number Generator */ + +/* Arduino SA product */ +#define USB_PRODUCT_ARDUINO_LEONARDO 0x8036 /* Leonardo */ + +/* Arkmicro products */ +#define USB_PRODUCT_ARKMICRO_ARK3116 0x0232 /* ARK3116 Serial */ + +/* Aruba products */ +#define USB_PRODUCT_ARUBA_CP210X 0xea60 /* CP210x Serial */ + +/* Asahi Optical products */ +#define USB_PRODUCT_ASAHIOPTICAL_OPTIO230 0x0004 /* PENTAX Optio230 */ + +/* Asante products */ +#define USB_PRODUCT_ASANTE_EA 0x1427 /* Ethernet */ + +/* ASIX Electronics products */ +#define USB_PRODUCT_ASIX_AX88172 0x1720 /* USB 2.0 10/100 Ethernet controller */ +#define USB_PRODUCT_ASIX_AX88178 0x1780 /* AX88178 */ +#define USB_PRODUCT_ASIX_AX88179 0x1790 /* AX88179 */ +#define USB_PRODUCT_ASIX_ASIX111 0x2790 /* ASIX111 */ +#define USB_PRODUCT_ASIX_ASIX112 0x2791 /* ASIX112 */ +#define USB_PRODUCT_ASIX_AX88772 0x7720 /* AX88772 */ +#define USB_PRODUCT_ASIX_AX88772A 0x772a /* AX88772A */ +#define USB_PRODUCT_ASIX_AX88772B 0x772b /* AX88772B */ +#define USB_PRODUCT_ASIX_AX88772B_1 0x7e2b /* AX88772B */ + +/* Askey Computer products */ +#define USB_PRODUCT_ASKEY_WLL013I 0x0320 /* WLL013 (Intersil) */ +#define USB_PRODUCT_ASKEY_WLL013 0x0321 /* WLL013 */ +#define USB_PRODUCT_ASKEY_VOYAGER1010 0x0821 /* Voyager 1010 */ + +/* ASUS products */ +#define USB_PRODUCT_ASUS_RT2570 0x1706 /* RT2570 */ +#define USB_PRODUCT_ASUS_RT2570_2 0x1707 /* RT2570 */ +#define USB_PRODUCT_ASUS_WL159G 0x170c /* WL-159g */ +#define USB_PRODUCT_ASUS_A9T_WIFI 0x171b /* A9T wireless */ +#define USB_PRODUCT_ASUS_P5B_WIFI 0x171d /* P5B wireless */ +#define USB_PRODUCT_ASUS_RT2573_1 0x1723 /* RT2573 */ +#define USB_PRODUCT_ASUS_RT2573_2 0x1724 /* RT2573 */ +#define USB_PRODUCT_ASUS_RT2870_1 0x1731 /* RT2870 */ +#define USB_PRODUCT_ASUS_RT2870_2 0x1732 /* RT2870 */ +#define USB_PRODUCT_ASUS_RT2870_3 0x1742 /* RT2870 */ +#define USB_PRODUCT_ASUS_RT2870_4 0x1760 /* RT2870 */ +#define USB_PRODUCT_ASUS_RT2870_5 0x1761 /* RT2870 */ +#define USB_PRODUCT_ASUS_USBN13 0x1784 /* USB-N13 */ +#define USB_PRODUCT_ASUS_USBN10 0x1786 /* USB-N10 */ +#define USB_PRODUCT_ASUS_RT3070_1 0x1790 /* RT3070 */ +#define USB_PRODUCT_ASUS_RTL8192SU_1 0x1791 /* RTL8192SU */ +#define USB_PRODUCT_ASUS_USBN53 0x179d /* USB-N53 */ +#define USB_PRODUCT_ASUS_RTL8192CU 0x17ab /* RTL8192CU */ +#define USB_PRODUCT_ASUS_USBN66 0x17ad /* USB-N66 */ +#define USB_PRODUCT_ASUS_RTL8192CU_2 0x17ba /* RTL8192CU */ +#define USB_PRODUCT_ASUS_RTL8192CU_3 0x17c0 /* RTL8192CU */ +#define USB_PRODUCT_ASUS_USBN10V2 0x17d3 /* USB-N10 v2 */ +#define USB_PRODUCT_ASUS_RTL8156 0x18d1 /* RTL8156 */ +#define USB_PRODUCT_ASUS_RTL8188EUS 0x18f0 /* RTL8188EUS */ +#define USB_PRODUCT_ASUS_MYPAL_A730 0x4202 /* MyPal A730 */ +#define USB_PRODUCT_ASUS2_USBN11 0x0b05 /* USB-N11 */ + +/* ASUSTeK Computer products */ +#define USB_PRODUCT_ASUSTEK_WL140 0x3300 /* WL-140 */ + +/* ATen products */ +#define USB_PRODUCT_ATEN_UC1284 0x2001 /* Parallel */ +#define USB_PRODUCT_ATEN_UC10T 0x2002 /* 10Mbps Ethernet */ +#define USB_PRODUCT_ATEN_UC110T 0x2007 /* UC-110T Ethernet */ +#define USB_PRODUCT_ATEN_UC232A 0x2008 /* UC232A Serial */ +#define USB_PRODUCT_ATEN_UC210T 0x2009 /* UC210T Ethernet */ +#define USB_PRODUCT_ATEN_UC2324 0x2011 /* UC2324 Serial */ +#define USB_PRODUCT_ATEN_DSB650C 0x4000 /* DSB-650C */ + +/* Atheros Communications products */ +#define USB_PRODUCT_ATHEROS_AR5523 0x0001 /* AR5523 */ +#define USB_PRODUCT_ATHEROS_AR5523_NF 0x0002 /* AR5523 */ + +/* Atheros Communications(2) products */ +#define USB_PRODUCT_ATHEROS2_AR5523_1 0x0001 /* AR5523 */ +#define USB_PRODUCT_ATHEROS2_AR5523_1_NF 0x0002 /* AR5523 */ +#define USB_PRODUCT_ATHEROS2_AR5523_2 0x0003 /* AR5523 */ +#define USB_PRODUCT_ATHEROS2_AR5523_2_NF 0x0004 /* AR5523 */ +#define USB_PRODUCT_ATHEROS2_AR5523_3 0x0005 /* AR5523 */ +#define USB_PRODUCT_ATHEROS2_AR5523_3_NF 0x0006 /* AR5523 */ +#define USB_PRODUCT_ATHEROS2_TG121N 0x1001 /* TG121N */ +#define USB_PRODUCT_ATHEROS2_WN821NV2 0x1002 /* WN821NV2 */ +#define USB_PRODUCT_ATHEROS2_AR9271_1 0x1006 /* AR9271 */ +#define USB_PRODUCT_ATHEROS2_3CRUSBN275 0x1010 /* 3CRUSBN275 */ +#define USB_PRODUCT_ATHEROS2_WN612 0x1011 /* WN612 */ +#define USB_PRODUCT_ATHEROS2_AR3011 0x3000 /* AR3011 */ +#define USB_PRODUCT_ATHEROS2_AR9280 0x7010 /* AR9280+AR7010 */ +#define USB_PRODUCT_ATHEROS2_AR9287 0x7015 /* AR9287+AR7010 */ +#define USB_PRODUCT_ATHEROS2_AR9170 0x9170 /* AR9170 */ +#define USB_PRODUCT_ATHEROS2_AR9271_2 0x9271 /* AR9271 */ +#define USB_PRODUCT_ATHEROS2_AR9271_3 0xb003 /* AR9271 */ + +/* ATI products */ +#define USB_PRODUCT_ATI2_205 0xa001 /* USB Cable 205 */ + +/* Atmel Comp. products */ +#define USB_PRODUCT_ATMEL_STK541 0x2109 /* STK541 Zigbee */ +#define USB_PRODUCT_ATMEL_UHB124 0x3301 /* UHB124 hub */ +#define USB_PRODUCT_ATMEL_WN210 0x4102 /* W-Buddie WN210 */ +#define USB_PRODUCT_ATMEL_DWL900AP 0x5601 /* DWL-900AP Wireless access point */ +#define USB_PRODUCT_ATMEL_AT91_CDC_ACM 0x6119 /* AT91 CDC ACM */ +#define USB_PRODUCT_ATMEL_AT76C503I1 0x7603 /* AT76C503 (Intersil 3861 Radio) */ +#define USB_PRODUCT_ATMEL_AT76C503I2 0x7604 /* AT76C503 (Intersil 3863 Radio) */ +#define USB_PRODUCT_ATMEL_AT76C503RFMD 0x7605 /* AT76C503 (RFMD Radio) */ +#define USB_PRODUCT_ATMEL_AT76C505RFMD 0x7606 /* AT76C505 (RFMD Radio) */ +#define USB_PRODUCT_ATMEL_AT76C505RFMD2958 0x7613 /* AT76C505 (RFMD 2958 Radio) */ +#define USB_PRODUCT_ATMEL_AT76C505A 0x7614 /* AT76C505A (RFMD 2958 Radio) */ +#define USB_PRODUCT_ATMEL_AT76C505AS 0x7617 /* AT76C505AS (RFMD 2958 Radio) */ + +/* Audio-Technica products */ +#define USB_PRODUCT_AUDIOTECHNICA_ATCHA4USB 0x0009 /* ATC-HA4USB USB headphone */ + +/* Avago Technologies products */ +#define USB_PRODUCT_AVAGO_MOUSE 0x0000 /* Mouse */ + +/* Avance Logic products */ +#define USB_PRODUCT_AVANCELOGIC_USBAUDIO 0x0100 /* USB Audio Speaker */ + +/* Averatec products */ +#define USB_PRODUCT_AVERATEC_USBWLAN 0x4013 /* WLAN */ + +/* Avision products */ +#define USB_PRODUCT_AVISION_1200U 0x0268 /* 1200U */ + +/* AVM products */ +#define USB_PRODUCT_AVM_FRITZWLAN 0x8401 /* FRITZ!WLAN N */ + +/* Axesstel products */ +#define USB_PRODUCT_AXESSTEL_DATAMODEM 0x1000 /* Data Modem */ + +/* AsureWave products */ +#define USB_PRODUCT_AZUREWAVE_RT2870_1 0x3247 /* RT2870 */ +#define USB_PRODUCT_AZUREWAVE_RT2870_2 0x3262 /* RT2870 */ +#define USB_PRODUCT_AZUREWAVE_RT3070_1 0x3273 /* RT3070 */ +#define USB_PRODUCT_AZUREWAVE_RT3070_2 0x3284 /* RT3070 */ +#define USB_PRODUCT_AZUREWAVE_RT3070_3 0x3305 /* RT3070 */ +#define USB_PRODUCT_AZUREWAVE_RTL8192SU_1 0x3306 /* RTL8192SU */ +#define USB_PRODUCT_AZUREWAVE_RT3070_4 0x3307 /* RT3070 */ +#define USB_PRODUCT_AZUREWAVE_RTL8192SU_2 0x3309 /* RTL8192SU */ +#define USB_PRODUCT_AZUREWAVE_RTL8192SU_3 0x3310 /* RTL8192SU */ +#define USB_PRODUCT_AZUREWAVE_RTL8192SU_4 0x3311 /* RTL8192SU */ +#define USB_PRODUCT_AZUREWAVE_RT3070_5 0x3321 /* RT3070 */ +#define USB_PRODUCT_AZUREWAVE_RTL8192SU_5 0x3325 /* RTL8192SU */ +#define USB_PRODUCT_AZUREWAVE_AR9271_1 0x3327 /* AR9271 */ +#define USB_PRODUCT_AZUREWAVE_AR9271_2 0x3328 /* AR9271 */ +#define USB_PRODUCT_AZUREWAVE_AR9271_3 0x3346 /* AR9271 */ +#define USB_PRODUCT_AZUREWAVE_AR9271_4 0x3348 /* AR9271 */ +#define USB_PRODUCT_AZUREWAVE_AR9271_5 0x3349 /* AR9271 */ +#define USB_PRODUCT_AZUREWAVE_AR9271_6 0x3350 /* AR9271 */ +#define USB_PRODUCT_AZUREWAVE_RTL8188CU 0x3357 /* RTL8188CU */ +#define USB_PRODUCT_AZUREWAVE_RTL8188CE_1 0x3358 /* RTL8188CE */ +#define USB_PRODUCT_AZUREWAVE_RTL8188CE_2 0x3359 /* RTL8188CE */ +#define USB_PRODUCT_AZUREWAVE_MT7601_1 0x3431 /* MT7601 */ +#define USB_PRODUCT_AZUREWAVE_MT7601_2 0x3434 /* MT7601 */ + +/* Baltech products */ +#define USB_PRODUCT_BALTECH_CARDREADER 0x9999 /* Card reader */ + +/* Bayer Health Care products */ +#define USB_PRODUCT_BAYER_CONTOUR 0x6001 /* Ascensia Contour */ + +/* B&B Electronics products */ +#define USB_PRODUCT_BBELECTR_USOTL4 0xac01 /* USOTL4 RS-422/485 */ +#define USB_PRODUCT_BBELECTR_USTL4 0xac02 /* USTL4 RS-422/485 */ +#define USB_PRODUCT_BBELECTR_USO9ML2 0xac03 /* USO9ML2 RS-232 */ +#define USB_PRODUCT_BBELECTR_USOPTL4 0xac11 /* USOPTL4 RS-422/485 */ +#define USB_PRODUCT_BBELECTR_USPTL4 0xac12 /* USPTL4 RS-422/485 */ +#define USB_PRODUCT_BBELECTR_USO9ML2DR2 0xac16 /* USO9ML2DR-2 RS-232 */ +#define USB_PRODUCT_BBELECTR_USO9ML2DR 0xac17 /* USO9ML2DR RS-232 */ +#define USB_PRODUCT_BBELECTR_USOPTL4DR2 0xac18 /* USOPTL4DR-2 RS-422/485 */ +#define USB_PRODUCT_BBELECTR_USOPTL4DR 0xac19 /* USOPTL4DR RS-422/485 */ +#define USB_PRODUCT_BBELECTR_485USB9F2W 0xac25 /* 485USB9F-2W RS-422/485 */ +#define USB_PRODUCT_BBELECTR_485USB9F4W 0xac26 /* 485USB9F-4W RS-422/485 */ +#define USB_PRODUCT_BBELECTR_232USB9M 0xac27 /* 232USB9M RS-232 */ +#define USB_PRODUCT_BBELECTR_485USBTB_2W 0xac33 /* 485USBTB-2W RS-422/485 */ +#define USB_PRODUCT_BBELECTR_485USBTB_4W 0xac34 /* 485USBTB-4W RS-422/485 */ +#define USB_PRODUCT_BBELECTR_TTL5USB9M 0xac49 /* TTL5USB9M */ +#define USB_PRODUCT_BBELECTR_TTL3USB9M 0xac50 /* TTL3USB9M */ +#define USB_PRODUCT_BBELECTR_ZZ_PROG1 0xba02 /* ZZ Programmer */ + +/* Belkin products */ +/*product BELKIN F5U111 0x???? F5U111 Ethernet */ +#define USB_PRODUCT_BELKIN_F5D6050 0x0050 /* F5D6050 802.11b Wireless adapter */ +#define USB_PRODUCT_BELKIN_FBT001V 0x0081 /* Bluetooth */ +#define USB_PRODUCT_BELKIN_F8T003V 0x0083 /* Bluetooth */ +#define USB_PRODUCT_BELKIN_FBT003V 0x0084 /* Bluetooth */ +#define USB_PRODUCT_BELKIN_F5U103 0x0103 /* F5U103 Serial */ +#define USB_PRODUCT_BELKIN_F5U109 0x0109 /* F5U109 Serial */ +#define USB_PRODUCT_BELKIN_SCSI 0x0115 /* SCSI */ +#define USB_PRODUCT_BELKIN_F5D5050 0x0121 /* F5D5050 Ethernet */ +#define USB_PRODUCT_BELKIN_F5U234 0x0234 /* F5U234 USB 2.0 4-Port Hub */ +#define USB_PRODUCT_BELKIN_F5U237 0x0237 /* F5U237 USB 2.0 7-Port Hub */ +#define USB_PRODUCT_BELKIN_F5U257 0x0257 /* F5U257 Serial */ +#define USB_PRODUCT_BELKIN_F6H375 0x0375 /* F6H375 UPS */ +#define USB_PRODUCT_BELKIN_F5U409 0x0409 /* F5U409 Serial */ +#define USB_PRODUCT_BELKIN_RTL8152B 0x047a /* RTL8152B */ +#define USB_PRODUCT_BELKIN_RTL8153 0x048a /* RTL8153 */ +#define USB_PRODUCT_BELKIN_F6C550AVR 0x0551 /* F6C550-AVR UPS */ +#define USB_PRODUCT_BELKIN_F6C1250EITWRK 0x0750 /* F6C1250EITW-RK UPS */ +#define USB_PRODUCT_BELKIN_F6C1500EITWRK 0x0751 /* F6C1500EITW-RK UPS */ +#define USB_PRODUCT_BELKIN_F6C900 0x0900 /* F6C900 UPS */ +#define USB_PRODUCT_BELKIN_F6C100 0x0910 /* F6C100 UPS */ +#define USB_PRODUCT_BELKIN_F6C120 0x0912 /* F6C120 UPS */ +#define USB_PRODUCT_BELKIN_F6C800 0x0980 /* F6C800 UPS */ +#define USB_PRODUCT_BELKIN_F9L1004V1 0x1004 /* F9L1004V1 */ +#define USB_PRODUCT_BELKIN_F6C1100 0x1100 /* F6C1100/1200 UPS */ +#define USB_PRODUCT_BELKIN_RTL8188CU 0x1102 /* RTL8188CU */ +#define USB_PRODUCT_BELKIN_F9L1103 0x1103 /* F9L1103 Wireless Adapter */ +#define USB_PRODUCT_BELKIN_RTL8188CUS 0x11f2 /* RTL8188CUS */ +#define USB_PRODUCT_BELKIN_F5U120 0x1203 /* F5U120-PC Hub */ +#define USB_PRODUCT_BELKIN_RTL8192CU 0x2102 /* RTL8192CU */ +#define USB_PRODUCT_BELKIN_F7D2102 0x2103 /* F7D2102 */ +#define USB_PRODUCT_BELKIN_RTL8192CU_1 0x21f2 /* RTL8192CU */ +#define USB_PRODUCT_BELKIN_ZD1211B 0x4050 /* ZD1211B */ +#define USB_PRODUCT_BELKIN_F5D5055 0x5055 /* F5D5055 */ +#define USB_PRODUCT_BELKIN_F5D7050 0x7050 /* F5D7050 54g USB Network Adapter */ +#define USB_PRODUCT_BELKIN_F5D7050A 0x705a /* F5D705A 54g USB Network Adapter */ +#define USB_PRODUCT_BELKIN_F5D7050C 0x705c /* F5D705C 54g USB Network Adapter */ +#define USB_PRODUCT_BELKIN_F5D7050E 0x705e /* F5D705E 54g USB Network Adapter */ +#define USB_PRODUCT_BELKIN_RT2870_1 0x8053 /* RT2870 */ +#define USB_PRODUCT_BELKIN_RT2870_2 0x805c /* RT2870 */ +#define USB_PRODUCT_BELKIN_F5D8053V3 0x815c /* F5D8053 v3 */ +#define USB_PRODUCT_BELKIN_RTL8192SU_1 0x815f /* RTL8192SU */ +#define USB_PRODUCT_BELKIN_F5D8055 0x825a /* F5D8055 */ +#define USB_PRODUCT_BELKIN_F5D8055V2 0x825b /* F5D8055 v2 */ +#define USB_PRODUCT_BELKIN_RTL8192SU_2 0x845a /* RTL8192SU */ +#define USB_PRODUCT_BELKIN_F5D9050V3 0x905b /* F5D9050 ver 3 */ +#define USB_PRODUCT_BELKIN_F5D9050C 0x905c /* F5D9050C */ +#define USB_PRODUCT_BELKIN_F6D4050V1 0x935a /* F6D4050 ver 1 */ +#define USB_PRODUCT_BELKIN_F6D4050V2 0x935b /* F6D4050 ver 2 */ +#define USB_PRODUCT_BELKIN_RTL8192SU_3 0x945a /* RTL8192SU */ +#define USB_PRODUCT_BELKIN_F7D1101V2 0x945b /* F7D1101 v2 */ + +/* Belkin(2) products */ +#define USB_PRODUCT_BELKIN2_F5U002 0x0002 /* F5U002 Parallel */ + +/* Bewan products */ +#define USB_PRODUCT_BEWAN_BWIFI_USB54AR 0x1196 /* BWIFI-USB54AR */ +#define USB_PRODUCT_BEWAN_RT3070 0x7712 /* RT3070 */ + +/* Billionton products */ +#define USB_PRODUCT_BILLIONTON_USB100 0x0986 /* USB100N 10/100 Ethernet */ +#define USB_PRODUCT_BILLIONTON_USBLP100 0x0987 /* USB100LP */ +#define USB_PRODUCT_BILLIONTON_USBEL100 0x0988 /* USB100EL */ +#define USB_PRODUCT_BILLIONTON_USBE100 0x8511 /* USBE100 */ +#define USB_PRODUCT_BILLIONTON_USB2AR 0x90ff /* USB2AR Ethernet */ + +/* Broadcom products */ +#define USB_PRODUCT_BROADCOM_BCMFW 0x0bdc /* BCMFW */ +#define USB_PRODUCT_BROADCOM_BCM2033 0x2000 /* BCM2033 */ +#define USB_PRODUCT_BROADCOM_BCM2033NF 0x2033 /* BCM2033 (no fw) */ +#define USB_PRODUCT_BROADCOM_BCM43236 0xbd17 /* BCM43236 */ +#define USB_PRODUCT_BROADCOM_BCM43143 0xbd1e /* BCM43143 */ +#define USB_PRODUCT_BROADCOM_BCM43242 0xbd1f /* BCM43242 */ +#define USB_PRODUCT_BROADCOM_BCM43569 0xbd27 /* BCM43569 */ + +/* Brother Industries products */ +#define USB_PRODUCT_BROTHER_HL1050 0x0002 /* HL-1050 laser printer */ +#define USB_PRODUCT_BROTHER_MFC210C 0x0161 /* MFC 210C */ + +/* Behavior Technology Computer products */ +#define USB_PRODUCT_BTC_BTC7932 0x6782 /* Keyboard/Mouse */ + +/* Bernd Walter Computer Technology products */ +#define USB_PRODUCT_BWCT_6CHCONSER 0x0001 /* 6ch ConSer */ + +/* CACE Technologies products */ +#define USB_PRODUCT_CACE_AIRPCAPNX 0x0300 /* AirPcap Nx */ + +/* Canon, Inc. products */ +#define USB_PRODUCT_CANON_N656U 0x2206 /* CANOSCAN N656U */ +#define USB_PRODUCT_CANON_N1220U 0x2207 /* CANOSCAN N1220U */ +#define USB_PRODUCT_CANON_N670U 0x220d /* CANOSCAN N670U */ +#define USB_PRODUCT_CANON_N1240U 0x220e /* CANOSCAN N1240U */ +#define USB_PRODUCT_CANON_LIDE60 0x221c /* CANOSCAN LiDE60 */ +#define USB_PRODUCT_CANON_S10 0x3041 /* PowerShot S10 */ +#define USB_PRODUCT_CANON_S20 0x3043 /* PowerShot S20 */ +#define USB_PRODUCT_CANON_S100_US 0x3045 /* PowerShot S100 */ +#define USB_PRODUCT_CANON_S100_EU 0x3047 /* PowerShot S100 */ +#define USB_PRODUCT_CANON_G1 0x3048 /* PowerShot G1 */ +#define USB_PRODUCT_CANON_A20 0x304e /* PowerShot A20 */ +#define USB_PRODUCT_CANON_A540 0x311b /* PowerShot A540 */ +#define USB_PRODUCT_CANON_SX100 0x315e /* PowerShot SX100 */ + +/* CASIO products */ +#define USB_PRODUCT_CASIO_QV 0x1001 /* QV */ +#define USB_PRODUCT_CASIO_BE300 0x2002 /* BE-300 PDA */ +#define USB_PRODUCT_CASIO_NAMELAND 0x4001 /* CASIO Nameland EZ-USB */ + +/* CATC products */ +#define USB_PRODUCT_CATC_NETMATE 0x000a /* Netmate Ethernet */ +#define USB_PRODUCT_CATC_NETMATE2 0x000c /* Netmate2 Ethernet */ +#define USB_PRODUCT_CATC_CHIEF 0x000d /* USB Chief Bus & Protocol Analyzer */ +#define USB_PRODUCT_CATC_ANDROMEDA 0x1237 /* Andromeda hub */ + +/* CCYU Technology products */ +#define USB_PRODUCT_CCYU_EASYDISK 0x2136 /* EasyDisk Portable */ + +/* Chen-Source products */ +#define USB_PRODUCT_CHENSOURCE_CM12402 0x933d /* CM12402 Eagle IR Cam */ + +/* Cherry products */ +#define USB_PRODUCT_CHERRY_MY3000KBD 0x0001 /* My3000 keyboard */ +#define USB_PRODUCT_CHERRY_MY3000HUB 0x0003 /* My3000 hub */ + +/* Chic Technology products */ +#define USB_PRODUCT_CHIC_MOUSE1 0x0001 /* mouse */ +#define USB_PRODUCT_CHIC_CYPRESS 0x0003 /* Cypress */ + +/* Chicony products */ +#define USB_PRODUCT_CHICONY_KB8933 0x0001 /* KB-8933 keyboard */ +#define USB_PRODUCT_CHICONY_CAMERA 0x480c /* Integrated Camera */ +#define USB_PRODUCT_CHICONY_RTL8188CUS_1 0xaff7 /* RTL8188CUS */ +#define USB_PRODUCT_CHICONY_RTL8188CUS_2 0xaff8 /* RTL8188CUS */ +#define USB_PRODUCT_CHICONY_RTL8188CUS_3 0xaff9 /* RTL8188CUS */ +#define USB_PRODUCT_CHICONY_RTL8188CUS_4 0xaffa /* RTL8188CUS */ +#define USB_PRODUCT_CHICONY_RTL8188CUS_5 0xaffb /* RTL8188CUS */ +#define USB_PRODUCT_CHICONY_RTL8188CUS_6 0xaffc /* RTL8188CUS */ +#define USB_PRODUCT_CHICONY_IRCAMERA 0xb615 /* Integrated IR Camera */ + +/* CH Products */ +#define USB_PRODUCT_CHPRODUCTS_PROTHROTTLE 0x00f1 /* Pro Throttle */ +#define USB_PRODUCT_CHPRODUCTS_PROPEDALS 0x00f2 /* Pro Pedals */ +#define USB_PRODUCT_CHPRODUCTS_FIGHTERSTICK 0x00f3 /* Fighterstick */ +#define USB_PRODUCT_CHPRODUCTS_FLIGHTYOKE 0x00ff /* Flight Sim Yoke */ + +/* Cisco-Linksys products */ +#define USB_PRODUCT_CISCOLINKSYS_WUSB54GV2 0x000a /* WUSB54G v2 */ +#define USB_PRODUCT_CISCOLINKSYS_WUSB54AG 0x000c /* WUSB54AG */ +#define USB_PRODUCT_CISCOLINKSYS_WUSB54G 0x000d /* RT2570 */ +#define USB_PRODUCT_CISCOLINKSYS_WUSB54GP 0x0011 /* RT2570 */ +#define USB_PRODUCT_CISCOLINKSYS_USB200MV2 0x0018 /* USB200M v2 */ +#define USB_PRODUCT_CISCOLINKSYS_HU200TS 0x001a /* HU200-TS */ +#define USB_PRODUCT_CISCOLINKSYS_WUSB54GC 0x0020 /* WUSB54GC */ +#define USB_PRODUCT_CISCOLINKSYS_WUSB54GR 0x0023 /* WUSB54GR */ +#define USB_PRODUCT_CISCOLINKSYS_WUSBF54G 0x0024 /* WUSBF54G */ +#define USB_PRODUCT_CISCOLINKSYS_WUSB200 0x0028 /* WUSB200 */ +#define USB_PRODUCT_CISCOLINKSYS_AE1000 0x002f /* AE1000 */ +#define USB_PRODUCT_CISCOLINKSYS_AM10 0x0031 /* AM10 */ +#define USB_PRODUCT_CISCOLINKSYS_USB3GIGV1 0x0041 /* USB3GIGV1 */ +#define USB_PRODUCT_CISCOLINKSYS2_RT3070 0x4001 /* RT3070 */ +#define USB_PRODUCT_CISCOLINKSYS3_RT3070 0x0101 /* RT3070 */ + +/* CLEVO products */ +#define USB_PRODUCT_CLEVO_RTL8153B 0x5101 /* RTL8153B */ + +/* Clipsal products */ +#define USB_PRODUCT_CLIPSAL_560884 0x0101 /* 560884 C-Bus Switch */ +#define USB_PRODUCT_CLIPSAL_5500PACA 0x0201 /* 5500PACA C-Bus Controller */ +#define USB_PRODUCT_CLIPSAL_5800PC 0x0301 /* 5800PC C-Bus Wireless */ +#define USB_PRODUCT_CLIPSAL_5500PCU 0x0303 /* 5500PCU C-Bus */ +#define USB_PRODUCT_CLIPSAL_5000CT2 0x0304 /* 5000CT2 C-Bus Touch Screen */ +#define USB_PRODUCT_CLIPSAL_C5000CT2 0x0305 /* C5000CT2 C-Bus Touch Screen */ +#define USB_PRODUCT_CLIPSAL_L51XX 0x0401 /* L51xx C-Bus Dimmer */ + +/* Club 3D products */ +#define USB_PRODUCT_CLUB3D_RTL8153 0x8153 /* RTL8153 */ + +/* CMOTECH CDMA Technologies products */ +#define USB_PRODUCT_CMOTECH_CNU510 0x5141 /* CDMA Technologies USB modem */ +#define USB_PRODUCT_CMOTECH_CM5100P 0x5523 /* CM-5100P EVDO */ +#define USB_PRODUCT_CMOTECH_CCU550 0x5533 /* CCU-550 EVDO */ +#define USB_PRODUCT_CMOTECH_CNU550PRO 0x5543 /* CNU-550pro EVDO */ +#define USB_PRODUCT_CMOTECH_CGU628 0x6006 /* CGU-628 */ +#define USB_PRODUCT_CMOTECH_CNU680 0x6803 /* CNU-680 */ +#define USB_PRODUCT_CMOTECH_CGU628_DISK 0xf000 /* CGU-628 disk mode */ + +/* Compaq products */ +#define USB_PRODUCT_COMPAQ_IPAQPOCKETPC 0x0003 /* iPAQ PocketPC */ +#define USB_PRODUCT_COMPAQ_A1500 0x0012 /* A1500 */ +#define USB_PRODUCT_COMPAQ_IPAQWLAN 0x0032 /* iPAQ WLAN */ +#define USB_PRODUCT_COMPAQ_W100 0x0033 /* W100 */ +#define USB_PRODUCT_COMPAQ_W200 0x0076 /* WLAN MultiPort W200 */ +#define USB_PRODUCT_COMPAQ_PJB100 0x504a /* Personal Jukebox PJB100 */ +#define USB_PRODUCT_COMPAQ_IPAQLINUX 0x505a /* iPAQ Linux */ + +/* Compare products */ +#define USB_PRODUCT_COMPARE_RTL8192CU 0x8010 /* RTL8192CU */ + +/* Conceptronic products */ +#define USB_PRODUCT_CONCEPTRONIC_PRISM_GT 0x3762 /* PrismGT USB 2.0 WLAN */ +#define USB_PRODUCT_CONCEPTRONIC_C11U 0x7100 /* C11U */ +#define USB_PRODUCT_CONCEPTRONIC_WL210 0x7110 /* WL-210 */ +#define USB_PRODUCT_CONCEPTRONIC_AR5523_1 0x7801 /* AR5523 */ +#define USB_PRODUCT_CONCEPTRONIC_AR5523_1_NF 0x7802 /* AR5523 */ +#define USB_PRODUCT_CONCEPTRONIC_AR5523_2 0x7811 /* AR5523 */ +#define USB_PRODUCT_CONCEPTRONIC_AR5523_2_NF 0x7812 /* AR5523 */ + +/* Conceptronic(2) products */ +#define USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_1 0x3300 /* RTL8192SU */ +#define USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_2 0x3301 /* RTL8192SU */ +#define USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_3 0x3302 /* RTL8192SU */ +#define USB_PRODUCT_CONCEPTRONIC2_C54RU 0x3c02 /* C54RU WLAN */ +#define USB_PRODUCT_CONCEPTRONIC2_RT2870_1 0x3c06 /* RT2870 */ +#define USB_PRODUCT_CONCEPTRONIC2_RT2870_2 0x3c07 /* RT2870 */ +#define USB_PRODUCT_CONCEPTRONIC2_RT3070_1 0x3c08 /* RT3070 */ +#define USB_PRODUCT_CONCEPTRONIC2_RT2870_7 0x3c09 /* RT2870 */ +#define USB_PRODUCT_CONCEPTRONIC2_RT3070_2 0x3c11 /* RT3070 */ +#define USB_PRODUCT_CONCEPTRONIC2_RT2870_8 0x3c12 /* RT2870 */ +#define USB_PRODUCT_CONCEPTRONIC2_C54RU2 0x3c22 /* C54RU */ +#define USB_PRODUCT_CONCEPTRONIC2_RT2870_3 0x3c23 /* RT2870 */ +#define USB_PRODUCT_CONCEPTRONIC2_RT2573 0x3c24 /* RT2573M */ +#define USB_PRODUCT_CONCEPTRONIC2_VIGORN61 0x3c25 /* VIGORN61 */ +#define USB_PRODUCT_CONCEPTRONIC2_RT2870_5 0x3c27 /* RT2870 */ +#define USB_PRODUCT_CONCEPTRONIC2_RT2870_6 0x3c28 /* RT2870 */ +#define USB_PRODUCT_CONCEPTRONIC2_RT3070_3 0x3c2c /* RT3070 */ + +/* Concord Camera products */ +#define USB_PRODUCT_CONCORDCAMERA_EYE_Q_3X 0x0100 /* Eye Q 3x */ + +/* Connectix products */ +#define USB_PRODUCT_CONNECTIX_QUICKCAM 0x0001 /* QuickCam */ + +/* Corega products */ +#define USB_PRODUCT_COREGA_ETHER_USB_T 0x0001 /* Ether USB-T */ +#define USB_PRODUCT_COREGA_FETHER_USB_TX 0x0004 /* FEther USB-TX */ +#define USB_PRODUCT_COREGA_WLAN_USB_USB_11 0x000c /* WirelessLAN USB-11 */ +#define USB_PRODUCT_COREGA_FETHER_USB_TXS 0x000d /* FEther USB-TXS */ +#define USB_PRODUCT_COREGA_WLANUSB 0x0012 /* Wireless LAN Stick-11 */ +#define USB_PRODUCT_COREGA_FETHER_USB2_TX 0x0017 /* FEther USB2-TX */ +#define USB_PRODUCT_COREGA_WLUSB_11_KEY 0x001a /* ULUSB-11 Key */ +#define USB_PRODUCT_COREGA_CGWLUSB2GL 0x002d /* CG-WLUSB2GL */ +#define USB_PRODUCT_COREGA_CGWLUSB2GPX 0x002e /* CG-WLUSB2GPX */ +#define USB_PRODUCT_COREGA_RT2870_1 0x002f /* RT2870 */ +#define USB_PRODUCT_COREGA_RT2870_2 0x003c /* RT2870 */ +#define USB_PRODUCT_COREGA_RT2870_3 0x003f /* RT2870 */ +#define USB_PRODUCT_COREGA_RT3070 0x0041 /* RT3070 */ +#define USB_PRODUCT_COREGA_CGWLUSB300GNM 0x0042 /* CG-WLUSB300GNM */ +#define USB_PRODUCT_COREGA_CGWLUSB300N 0x0043 /* CG-WLUSB300N */ +#define USB_PRODUCT_COREGA_RTL8192SU 0x0047 /* RTL8192SU */ +#define USB_PRODUCT_COREGA_RTL8192CU 0x0056 /* RTL8192CU */ +#define USB_PRODUCT_COREGA_WLUSB_11_STICK 0x7613 /* WLAN USB Stick 11 */ +#define USB_PRODUCT_COREGA_FETHER_USB_TXC 0x9601 /* FEther USB-TXC */ + +/* Corsair products */ +#define USB_PRODUCT_CORSAIR_CP210X 0x1c00 /* CP210X */ + +/* Creative Labs products */ +#define USB_PRODUCT_CREATIVE_NOMAD_II 0x1002 /* Nomad II */ +#define USB_PRODUCT_CREATIVE_EMU0202 0x3f02 /* E-Mu 0202 */ +#define USB_PRODUCT_CREATIVE_NOMAD_IIMG 0x4004 /* Nomad II MG */ +#define USB_PRODUCT_CREATIVE_NOMAD 0x4106 /* Nomad */ +#define USB_PRODUCT_CREATIVE2_VOIP_BLASTER 0x0258 /* Voip Blaster */ + +/* Cambridge Silicon Radio products */ +#define USB_PRODUCT_CSR_BLUETOOTH 0x0001 /* Bluetooth */ +#define USB_PRODUCT_CSR_BLUECORE 0x1000 /* BlueCore */ + +/* CONWISE Technology products */ +#define USB_PRODUCT_CTC_CW6622 0x6622 /* CW6622 */ + +/* CTX products */ +#define USB_PRODUCT_CTX_EX1300 0x9999 /* Ex1300 hub */ + +/* CyberPower products */ +#define USB_PRODUCT_CYBERPOWER_UPS 0x0005 /* UPS */ +#define USB_PRODUCT_CYBERPOWER_1500 0x0501 /* 1500 UPS */ +#define USB_PRODUCT_CYBERPOWER_OR2200 0x0601 /* OR2200 UPS */ + +/* CyberTAN Technology products */ +#define USB_PRODUCT_CYBERTAN_GIGASET108 0x160c /* Siemens Gigaset 108 */ +#define USB_PRODUCT_CYBERTAN_TG54USB 0x1666 /* TG54USB */ +#define USB_PRODUCT_CYBERTAN_ZD1211B 0x1667 /* ZD1211B */ +#define USB_PRODUCT_CYBERTAN_RT2870 0x1828 /* RT2870 */ + +/* Cypress Semiconductor products */ +#define USB_PRODUCT_CYPRESS_MOUSE 0x0001 /* mouse */ +#define USB_PRODUCT_CYPRESS_THERMO 0x0002 /* thermometer */ +#define USB_PRODUCT_CYPRESS_KBDHUB 0x0101 /* Keyboard/Hub */ +#define USB_PRODUCT_CYPRESS_FMRADIO 0x1002 /* FM Radio */ +#define USB_PRODUCT_CYPRESS_USBRS232 0x5500 /* RS232 */ +#define USB_PRODUCT_CYPRESS_HUB2 0x6560 /* USB2 Hub */ +#define USB_PRODUCT_CYPRESS_LPRDK 0xe001 /* CY4636 LP RDK Bridge */ +#define USB_PRODUCT_CYPRESS_SISPM_OLD 0xfd10 /* Sispm - old version */ +#define USB_PRODUCT_CYPRESS_SISPM 0xfd11 /* Sispm */ +#define USB_PRODUCT_CYPRESS_SISPM_FLASH 0xfd12 /* Sispm - flash */ + +/* Daisy Technology products */ +#define USB_PRODUCT_DAISY_DMC 0x6901 /* PhotoClip */ + +/* Dallas Semiconductor products */ +#define USB_PRODUCT_DALLAS_USB_FOB_IBUTTON 0x2490 /* USB-FOB/iBUTTON */ +#define USB_PRODUCT_DALLAS_J6502 0x4201 /* J-6502 speakers */ + +/* DataApex products */ +#define USB_PRODUCT_DATAAPEX_MULTICOM 0xead6 /* MultiCom */ + +/* Davicom products */ +#define USB_PRODUCT_DAVICOM_WK668 0x0668 /* HenTong WK-668 */ +#define USB_PRODUCT_DAVICOM_DM9601 0x9601 /* DM9601 */ + +/* Dell products */ +#define USB_PRODUCT_DELL_AXIM 0x4005 /* Axim X51v */ +#define USB_PRODUCT_DELL_BC02 0x8000 /* Bluetooth */ +#define USB_PRODUCT_DELL_TM1180 0x8100 /* TrueMobile 1180 WLAN */ +#define USB_PRODUCT_DELL_PRISM_GT_1 0x8102 /* PrismGT USB 2.0 WLAN */ +#define USB_PRODUCT_DELL_BLUETOOTH350 0x8103 /* Bluetooth */ +#define USB_PRODUCT_DELL_PRISM_GT_2 0x8104 /* PrismGT USB 2.0 WLAN */ +#define USB_PRODUCT_DELL_W5500 0x8115 /* W5500 HSDPA */ +#define USB_PRODUCT_DELL_U740 0x8135 /* U740 CDMA */ +#define USB_PRODUCT_DELL_EU870D 0x8138 /* EU870D HSDPA */ +#define USB_PRODUCT_DELL_DW5821E 0x81d7 /* DW5821e LTE */ +#define USB_PRODUCT_DELL_DW700 0x9500 /* DW700 GPS */ +#define USB_PRODUCT_DELL2_UPS 0xffff /* UPS */ + +/* DeLorme products */ +#define USB_PRODUCT_DELORME_EMUSB 0x0100 /* Earthmate GPS */ +#define USB_PRODUCT_DELORME_EMLT20 0x0200 /* Earthmate LT20 */ + +/* Diamond products */ +#define USB_PRODUCT_DIAMOND_RIO500USB 0x0001 /* Rio 500 */ + +/* Supra products */ +#define USB_PRODUCT_DIAMOND2_SUPRAEXPRESS56K 0x07da /* Supra Express 56K */ +#define USB_PRODUCT_DIAMOND2_SUPRA2890 0x0b4a /* SupraMax 2890 56K */ +#define USB_PRODUCT_DIAMOND2_RIO600USB 0x5001 /* Rio 600 */ +#define USB_PRODUCT_DIAMOND2_RIO800USB 0x5002 /* Rio 800 */ +#define USB_PRODUCT_DIAMOND2_PSAPLAY120 0x5003 /* Nike psa[play 120 */ + +/* Dick Smith Electronics (really C-Net) products */ +#define USB_PRODUCT_DICKSMITH_WL200U 0x0002 /* WL-200U */ +#define USB_PRODUCT_DICKSMITH_CHUSB611G 0x0013 /* CHUSB 611G */ +#define USB_PRODUCT_DICKSMITH_WL240U 0x0014 /* WL-240U */ +#define USB_PRODUCT_DICKSMITH_XH1153 0x5743 /* XH1153 802.11b */ +#define USB_PRODUCT_DICKSMITH_RT2573 0x9022 /* RT2573 */ +#define USB_PRODUCT_DICKSMITH_CWD854F 0x9032 /* C-Net CWD-854 rev F */ +#define USB_PRODUCT_DICKSMITH_RTL8187 0x9401 /* RTL8187 */ + +/* Digi International products */ +#define USB_PRODUCT_DIGI_ACCELEPORT2 0x0002 /* AccelePort 2 */ +#define USB_PRODUCT_DIGI_ACCELEPORT4 0x0004 /* AccelePort 4 */ +#define USB_PRODUCT_DIGI_ACCELEPORT8 0x0008 /* AccelePort 8 */ + +/* Digianswer A/S products */ +#define USB_PRODUCT_DIGIANSWER_ZIGBEE802154 0x000a /* ZigBee */ + +/* Digital Stream Corp. products */ +#define USB_PRODUCT_DIGITALSTREAM_PS2 0x0001 /* PS/2 Active */ + +/* DisplayLink products */ +#define USB_PRODUCT_DISPLAYLINK_GUC2020 0x0059 /* IOGEAR DVI GUC2020 */ +#define USB_PRODUCT_DISPLAYLINK_LD220 0x0100 /* Samsung LD220 */ +#define USB_PRODUCT_DISPLAYLINK_TOSHIBA 0x0110 /* TOSHIBA Video Dock */ +#define USB_PRODUCT_DISPLAYLINK_POLARIS2 0x0117 /* Polaris2 USB dock */ +#define USB_PRODUCT_DISPLAYLINK_VCUD60 0x0136 /* Rextron DVI */ +#define USB_PRODUCT_DISPLAYLINK_CONV 0x0138 /* StarTech CONV-USB2DVI */ +#define USB_PRODUCT_DISPLAYLINK_DLDVI 0x0141 /* DisplayLink DVI */ +#define USB_PRODUCT_DISPLAYLINK_VGA10 0x015a /* CMP-USBVGA10 */ +#define USB_PRODUCT_DISPLAYLINK_WSDVI 0x0198 /* WS Tech DVI */ +#define USB_PRODUCT_DISPLAYLINK_EC008 0x019b /* EasyCAP008 DVI */ +#define USB_PRODUCT_DISPLAYLINK_LCD4300U 0x01ba /* LCD-4300U */ +#define USB_PRODUCT_DISPLAYLINK_LCD8000U 0x01bb /* LCD-8000U */ +#define USB_PRODUCT_DISPLAYLINK_HPDOCK 0x01d4 /* HP USB Docking */ +#define USB_PRODUCT_DISPLAYLINK_NL571 0x01d7 /* HP USB DVI */ +#define USB_PRODUCT_DISPLAYLINK_M01061 0x01e2 /* Lenovo DVI */ +#define USB_PRODUCT_DISPLAYLINK_NBDOCK 0x0215 /* VideoHome NBdock1920 */ +#define USB_PRODUCT_DISPLAYLINK_SWDVI 0x024c /* SUNWEIT DVI */ +#define USB_PRODUCT_DISPLAYLINK_LUM70 0x02a9 /* Lilliput UM-70 */ +#define USB_PRODUCT_DISPLAYLINK_LT1421 0x03e0 /* Lenovo ThinkVision LT1421 */ +#define USB_PRODUCT_DISPLAYLINK_UM7X0 0x401a /* nanovision MiMo */ + +/* D-Link products */ +/*product DLINK DSBS25 0x0100 DSB-S25 serial */ +#define USB_PRODUCT_DLINK_DUBE100 0x1a00 /* 10/100 Ethernet */ +#define USB_PRODUCT_DLINK_DUBE100C1 0x1a02 /* DUB-E100 rev C1 */ +#define USB_PRODUCT_DLINK_DSB650TX4 0x200c /* 10/100 Ethernet */ +#define USB_PRODUCT_DLINK_DWL120E 0x3200 /* DWL-120 rev E */ +#define USB_PRODUCT_DLINK_DWA130C 0x3301 /* DWA-130 rev C */ +#define USB_PRODUCT_DLINK_RTL8192CU_1 0x3307 /* RTL8192CU */ +#define USB_PRODUCT_DLINK_RTL8188CU 0x3308 /* RTL8188CU */ +#define USB_PRODUCT_DLINK_RTL8192CU_2 0x3309 /* RTL8192CU */ +#define USB_PRODUCT_DLINK_RTL8192CU_3 0x330a /* RTL8192CU */ +#define USB_PRODUCT_DLINK_RTL8192CU_4 0x330b /* RTL8192CU */ +#define USB_PRODUCT_DLINK_DWA131B 0x330d /* DWA-131 rev B */ +#define USB_PRODUCT_DLINK_DWA125D1 0x330f /* DWA-125 rev D1 */ +#define USB_PRODUCT_DLINK_DWA123D1 0x3310 /* DWA-123 rev D1 */ +#define USB_PRODUCT_DLINK_DWA137A1 0x3317 /* DWA-137 rev A1 */ +#define USB_PRODUCT_DLINK_DWA131E1 0x3319 /* DWA-131 rev E1 */ +#define USB_PRODUCT_DLINK_DWA121B1 0x331b /* DWA-121 rev B1 */ +#define USB_PRODUCT_DLINK_DWA182D1 0x331c /* DWA-182 rev D1 */ +#define USB_PRODUCT_DLINK_DWA171C1 0x331d /* DWA-171 rev C1 */ +#define USB_PRODUCT_DLINK_DWL122 0x3700 /* DWL-122 */ +#define USB_PRODUCT_DLINK_DWLG120 0x3701 /* DWL-G120 */ +#define USB_PRODUCT_DLINK_DWL120F 0x3702 /* DWL-120 rev F */ +#define USB_PRODUCT_DLINK_DWLG122A2 0x3704 /* DWL-G122 rev A2 */ +#define USB_PRODUCT_DLINK_DWLAG132 0x3a00 /* DWL-AG132 */ +#define USB_PRODUCT_DLINK_DWLAG132_NF 0x3a01 /* DWL-AG132 */ +#define USB_PRODUCT_DLINK_DWLG132 0x3a02 /* DWL-G132 */ +#define USB_PRODUCT_DLINK_DWLG132_NF 0x3a03 /* DWL-G132 */ +#define USB_PRODUCT_DLINK_DWLAG122 0x3a04 /* DWL-AG122 */ +#define USB_PRODUCT_DLINK_DWLAG122_NF 0x3a05 /* DWL-AG122 */ +#define USB_PRODUCT_DLINK_RT2570 0x3c00 /* RT2570 */ +#define USB_PRODUCT_DLINK_DUBE100B1 0x3c05 /* DUB-E100 rev B1 */ +#define USB_PRODUCT_DLINK_RT2870 0x3c09 /* RT2870 */ +#define USB_PRODUCT_DLINK_RT3072 0x3c0a /* RT3072 */ +#define USB_PRODUCT_DLINK_DWA140B3 0x3c15 /* DWA-140 rev B3 */ +#define USB_PRODUCT_DLINK_DWA160B2 0x3c1a /* DWA-160 rev B2 */ +#define USB_PRODUCT_DLINK_DWA127 0x3c1b /* DWA-127 */ +#define USB_PRODUCT_DLINK_DWA125B2 0x3c1e /* DWA-125 rev B2 */ +#define USB_PRODUCT_DLINK_DWA162 0x3c1f /* DWA-162 Wireless Adapter */ +#define USB_PRODUCT_DLINK_DWA140D1 0x3c20 /* DWA-140 rev D1 */ +#define USB_PRODUCT_DLINK_DWA130F1 0x3c25 /* DWA-130 rev F1 */ +#define USB_PRODUCT_DLINK_DWA127B1 0x3d04 /* DWA-127 rev B1 */ +#define USB_PRODUCT_DLINK_DSB650C 0x4000 /* 10Mbps Ethernet */ +#define USB_PRODUCT_DLINK_DSB650TX1 0x4001 /* 10/100 Ethernet */ +#define USB_PRODUCT_DLINK_DSB650TX 0x4002 /* 10/100 Ethernet */ +#define USB_PRODUCT_DLINK_DSB650TX_PNA 0x4003 /* 1/10/100 Ethernet */ +#define USB_PRODUCT_DLINK_DSB650TX3 0x400b /* 10/100 Ethernet */ +#define USB_PRODUCT_DLINK_DSB650TX2 0x4102 /* 10/100 Ethernet */ +#define USB_PRODUCT_DLINK_DUB1312 0x4a00 /* DUB-1312 */ +#define USB_PRODUCT_DLINK_RTL8153_1 0x7e34 /* RTL8153 */ +#define USB_PRODUCT_DLINK_RTL8153_2 0xa710 /* RTL8153 */ +#define USB_PRODUCT_DLINK_DSB650 0xabc1 /* 10/100 Ethernet */ + +/* D-Link(2) products */ +#define USB_PRODUCT_DLINK2_RTL8192SU_1 0x3300 /* RTL8192SU */ +#define USB_PRODUCT_DLINK2_RTL8192SU_2 0x3302 /* RTL8192SU */ +#define USB_PRODUCT_DLINK2_DWA131A1 0x3303 /* DWA-131 A1 */ +#define USB_PRODUCT_DLINK2_WUA2340 0x3a07 /* WUA-2340 */ +#define USB_PRODUCT_DLINK2_WUA2340_NF 0x3a08 /* WUA-2340 */ +#define USB_PRODUCT_DLINK2_DWA160A2 0x3a09 /* DWA-160 A2 */ +#define USB_PRODUCT_DLINK2_DWA130D1 0x3a0f /* DWA-130 rev D1 */ +#define USB_PRODUCT_DLINK2_AR9271 0x3a10 /* AR9271 */ +#define USB_PRODUCT_DLINK2_DWLG122C1 0x3c03 /* DWL-G122 rev C1 */ +#define USB_PRODUCT_DLINK2_WUA1340 0x3c04 /* WUA-1340 */ +#define USB_PRODUCT_DLINK2_DWA111 0x3c06 /* DWA-111 */ +#define USB_PRODUCT_DLINK2_DWA110 0x3c07 /* DWA-110 */ +#define USB_PRODUCT_DLINK2_RT2870_1 0x3c09 /* RT2870 */ +#define USB_PRODUCT_DLINK2_RT3072 0x3c0a /* RT3072 */ +#define USB_PRODUCT_DLINK2_RT3072_1 0x3c0b /* RT3072 */ +#define USB_PRODUCT_DLINK2_RT3070_1 0x3c0d /* RT3070 */ +#define USB_PRODUCT_DLINK2_RT3070_2 0x3c0e /* RT3070 */ +#define USB_PRODUCT_DLINK2_RT3070_3 0x3c0f /* RT3070 */ +#define USB_PRODUCT_DLINK2_DWA160A1 0x3c10 /* DWA-160 A1 */ +#define USB_PRODUCT_DLINK2_RT2870_2 0x3c11 /* RT2870 */ +#define USB_PRODUCT_DLINK2_DWA130 0x3c13 /* DWA-130 */ +#define USB_PRODUCT_DLINK2_RT3070_4 0x3c15 /* RT3070 */ +#define USB_PRODUCT_DLINK2_RT3070_5 0x3c16 /* RT3070 */ + +/* D-Link(3) products */ +#define USB_PRODUCT_DLINK3_KVM221 0x020f /* KVM-221 */ + +/* DMI products */ +#define USB_PRODUCT_DMI_SA2_0 0xb001 /* Storage Adapter */ + +/* Domain Technologies products */ +#define USB_PRODUCT_DOMAIN_ROCKCHIP 0x3203 /* RockChip Media Player */ + +/* DrayTek products */ +#define USB_PRODUCT_DRAYTEK_VIGOR550 0x0550 /* Vigor550 */ +#define USB_PRODUCT_DRAYTEK_VIGOR600 0x0600 /* Vigor600 */ + +/* Dream Cheeky */ +#define USB_PRODUCT_DREAMCHEEKY_ROCKETBABY 0x0701 /* Missile Launcher */ + +/* Dream Link products */ +#define USB_PRODUCT_DREAMLINK_ULMB1 0x0013 /* USB LED Message Board v1.0 */ + +/* Dresden Elektronic products */ +#define USB_PRODUCT_DRESDENELEC_STB 0x0001 /* Sensor Terminal */ +#define USB_PRODUCT_DRESDENELEC_WHT 0x0004 /* Wireless Terminal */ + +/* DViCO products */ +#define USB_PRODUCT_DVICO_RT3070 0xb307 /* RT3070 */ + +/* Dynabook products */ +#define USB_PRODUCT_DYNABOOK_RTL8153B_1 0x0419 /* RTL8153B */ +#define USB_PRODUCT_DYNABOOK_RTL8153B_2 0x0425 /* RTL8153B */ + +/* Dynastream Innovations */ +#define USB_PRODUCT_DYNASTREAM_ANTDEVBOARD 0x1003 /* ANT dev board */ +#define USB_PRODUCT_DYNASTREAM_ANT2USB 0x1004 /* ANT2USB */ +#define USB_PRODUCT_DYNASTREAM_ANTDEVBOARD2 0x1006 /* ANT dev board */ +#define USB_PRODUCT_DYNASTREAM_ANTUSB2 0x1008 /* ANTUSB-2 Stick */ +#define USB_PRODUCT_DYNASTREAM_ANTUSBM 0x1009 /* ANTUSB-m Stick */ + +/* EasyDisk products */ +#define USB_PRODUCT_EASYDISK_EASYDISK 0x0005 /* Flash Disk */ + +/* EDIMAX products */ +#define USB_PRODUCT_EDIMAX_EW7318 0x7318 /* EW-7318 */ +#define USB_PRODUCT_EDIMAX_RTL8192SU_1 0x7611 /* RTL8192SU */ +#define USB_PRODUCT_EDIMAX_RTL8192SU_2 0x7612 /* RTL8192SU */ +#define USB_PRODUCT_EDIMAX_EW7618 0x7618 /* EW-7618 */ +#define USB_PRODUCT_EDIMAX_RTL8192SU_3 0x7622 /* RTL8192SU */ +#define USB_PRODUCT_EDIMAX_EW7711UANV2 0x7710 /* EW-7711UAn V2 */ +#define USB_PRODUCT_EDIMAX_RT2870_1 0x7711 /* RT2870 */ +#define USB_PRODUCT_EDIMAX_EW7717 0x7717 /* EW-7717 */ +#define USB_PRODUCT_EDIMAX_EW7718 0x7718 /* EW-7718 */ +#define USB_PRODUCT_EDIMAX_EW7722UTN 0x7722 /* EW-7722UTn */ +#define USB_PRODUCT_EDIMAX_EW7811UN 0x7811 /* EW-7811Un */ +#define USB_PRODUCT_EDIMAX_RTL8192CU 0x7822 /* RTL8192CU */ +#define USB_PRODUCT_EDIMAX_EW7611ULB 0xa611 /* EW-7611ULB */ +#define USB_PRODUCT_EDIMAX_EW7811UNV2 0xb811 /* EW-7811Un V2 */ +#define USB_PRODUCT_EDIMAX_EW7822ULC 0xb822 /* EW-7822ULC */ + +/* eGalax Products */ +#define USB_PRODUCT_EGALAX_TPANEL 0x0001 /* Touch Panel */ +#define USB_PRODUCT_EGALAX_TPANEL2 0x0002 /* Touch Panel */ +#define USB_PRODUCT_EGALAX2_TPANEL 0x0001 /* Touch Panel */ + +/* Eicon Networks products */ +#define USB_PRODUCT_EICON_DIVA852 0x4905 /* Diva 852 ISDN TA */ + +/* EIZO products */ +#define USB_PRODUCT_EIZO_HUB 0x0000 /* hub */ +#define USB_PRODUCT_EIZO_MONITOR 0x0001 /* monitor */ + +/* Elan Microelectronics products */ +#define USB_PRODUCT_ELAN_BARCODE 0x0001 /* Barcode Scanner */ + +/* ELCON Systemtechnik products */ +#define USB_PRODUCT_ELCON_PLAN 0x0002 /* Goldpfeil P-LAN */ + +/* Elecom products */ +#define USB_PRODUCT_ELECOM_MOUSE29UO 0x0002 /* 29UO */ +#define USB_PRODUCT_ELECOM_MXT3URBK 0x00fb /* M-XT3UR BK */ +#define USB_PRODUCT_ELECOM_MXT3DRBK 0x00fc /* M-XT3DR BK */ +#define USB_PRODUCT_ELECOM_MXT4DRBK 0x00fd /* M-XT4DR BK */ +#define USB_PRODUCT_ELECOM_MDT1URBK 0x00fe /* M-DT1UR BK */ +#define USB_PRODUCT_ELECOM_MDT1DRBK 0x00ff /* M-DT1DR BK */ +#define USB_PRODUCT_ELECOM_MHT1URBK 0x010c /* M-HT1UR BK */ +#define USB_PRODUCT_ELECOM_MHT1DRBK 0x010d /* M-HT1DR BK */ +#define USB_PRODUCT_ELECOM_LDUSBTX0 0x200c /* LD-USB/TX */ +#define USB_PRODUCT_ELECOM_LDUSBTX1 0x4002 /* LD-USB/TX */ +#define USB_PRODUCT_ELECOM_LDUSBLTX 0x4005 /* LD-USBL/TX */ +#define USB_PRODUCT_ELECOM_WDC150SU2M 0x4008 /* WDC-150SU2M */ +#define USB_PRODUCT_ELECOM_LDUSBTX2 0x400b /* LD-USB/TX */ +#define USB_PRODUCT_ELECOM_LDUSB20 0x4010 /* LD-USB20 */ +#define USB_PRODUCT_ELECOM_RTL8153B 0x4013 /* RTL8153B */ +#define USB_PRODUCT_ELECOM_RTL8156B 0x4017 /* RTL8156B */ +#define USB_PRODUCT_ELECOM_UCSGT 0x5003 /* UC-SGT Serial */ +#define USB_PRODUCT_ELECOM_UCSGT0 0x5004 /* UC-SGT0 Serial */ +#define USB_PRODUCT_ELECOM_LDUSBTX3 0xabc1 /* LD-USB/TX */ + +/* Elektor Electronics products */ +#define USB_PRODUCT_ELEKTOR_FT323R 0x0005 /* FT323R */ + +/* Elsa products */ +#define USB_PRODUCT_ELSA_MODEM1 0x2265 /* ELSA */ +#define USB_PRODUCT_ELSA_USB2ETHERNET 0x3000 /* Microlink USB2Ethernet */ + +/* ELV products */ +#define USB_PRODUCT_ELV_USBI2C 0xe00f /* USB-I2C */ + +/* eMPIA products */ +#define USB_PRODUCT_EMPIA_EEEPC701_VIDEO 0x2761 /* EeePC701 camera */ + +/* Encore products */ +#define USB_PRODUCT_ENCORE_RT3070_1 0x1480 /* RT3070 */ +#define USB_PRODUCT_ENCORE_RT3070_2 0x14a1 /* RT3070 */ +#define USB_PRODUCT_ENCORE_RT3070_3 0x14a9 /* RT3070 */ + +/* Entrega products */ +#define USB_PRODUCT_ENTREGA_1S 0x0001 /* 1S serial */ +#define USB_PRODUCT_ENTREGA_2S 0x0002 /* 2S serial */ +#define USB_PRODUCT_ENTREGA_1S25 0x0003 /* 1S25 serial */ +#define USB_PRODUCT_ENTREGA_4S 0x0004 /* 4S serial */ +#define USB_PRODUCT_ENTREGA_E45 0x0005 /* E45 Ethernet */ +#define USB_PRODUCT_ENTREGA_CENTRONICS 0x0006 /* Centronics */ +#define USB_PRODUCT_ENTREGA_XX1 0x0008 /* Ethernet */ +#define USB_PRODUCT_ENTREGA_1S9 0x0093 /* 1S9 serial */ +#define USB_PRODUCT_ENTREGA_EZUSB 0x8000 /* EZ-USB */ +/*product ENTREGA SERIAL 0x8001 DB25 Serial connector*/ +#define USB_PRODUCT_ENTREGA_2U4S 0x8004 /* 2U4S serial */ +#define USB_PRODUCT_ENTREGA_XX2 0x8005 /* Ethernet */ +/*product ENTREGA SERIAL_DB9 0x8093 DB9 Serial connector*/ + +/* Epson products */ +#define USB_PRODUCT_EPSON_PRINTER1 0x0001 /* USB Printer */ +#define USB_PRODUCT_EPSON_PRINTER2 0x0002 /* ISD Smart Cable for Mac */ +#define USB_PRODUCT_EPSON_PRINTER3 0x0003 /* ISD Smart Cable */ +#define USB_PRODUCT_EPSON_PRINTER5 0x0005 /* USB Printer */ +#define USB_PRODUCT_EPSON_636 0x0101 /* Perfection 636U / 636Photo */ +#define USB_PRODUCT_EPSON_610 0x0103 /* Perfection 610 */ +#define USB_PRODUCT_EPSON_1200 0x0104 /* Perfection 1200U / 1200Photo */ +#define USB_PRODUCT_EPSON_1600 0x0107 /* Expression 1600 */ +#define USB_PRODUCT_EPSON_1640 0x010a /* Perfection 1640SU */ +#define USB_PRODUCT_EPSON_1240 0x010b /* Perfection 1240U / 1240Photo */ +#define USB_PRODUCT_EPSON_640U 0x010c /* Perfection 640U */ +#define USB_PRODUCT_EPSON_1650 0x0110 /* Perfection 1650 */ +#define USB_PRODUCT_EPSON_GT9700F 0x0112 /* GT-9700F */ +#define USB_PRODUCT_EPSON_2400 0x011b /* Perfection 2400 */ +#define USB_PRODUCT_EPSON_1260 0x011d /* Perfection 1260 */ +#define USB_PRODUCT_EPSON_1660 0x011e /* Perfection 1660 */ +#define USB_PRODUCT_EPSON_1670 0x011f /* Perfection 1670 */ +#define USB_PRODUCT_EPSON_CX5400 0x0808 /* CX5400 */ +#define USB_PRODUCT_EPSON_CX3650 0x080e /* Stylus CX3650 */ +#define USB_PRODUCT_EPSON_DX3800 0x0818 /* Stylus DX3800 */ +#define USB_PRODUCT_EPSON_DX5000 0x082b /* Stylus DX5000 */ +#define USB_PRODUCT_EPSON_DX6000 0x082e /* Stylus DX6000 */ +#define USB_PRODUCT_EPSON_DX4000 0x082f /* Stylus DX4000 */ + +/* Ericsson products */ +#define USB_PRODUCT_ERICSSON_F5521GW 0x1911 /* Mobile Broadband Module */ + +/* e-TEK Labs products */ +#define USB_PRODUCT_ETEK_1COM 0x8007 /* Serial */ + +/* Evolution Robotics products */ +#define USB_PRODUCT_EVOLUTION_ER1 0x0300 /* ER1 Control Module */ +#define USB_PRODUCT_EVOLUTION_RCM4_1 0x0302 /* RCM4 interface */ +#define USB_PRODUCT_EVOLUTION_RCM4_2 0x0303 /* RCM4 interface */ + +/* Exar products */ +#define USB_PRODUCT_EXAR_XR21V1410 0x1410 /* XR21V1410 */ + +/* Extended Systems products */ +#define USB_PRODUCT_EXTENDED_XTNDACCESS 0x0100 /* XTNDAccess IrDA */ + +/* Falcom Wireless Communications GmbH products */ +#define USB_PRODUCT_FALCOM_TWIST 0x0001 /* Twist */ +#define USB_PRODUCT_FALCOM_SAMBA 0x0005 /* Samba */ + +/* FeiXun Communication products */ +#define USB_PRODUCT_FEIXUN_RTL8188CU 0x0090 /* RTL8188CU */ +#define USB_PRODUCT_FEIXUN_RTL8192CU 0x0091 /* RTL8192CU */ + +/* Festo products */ +#define USB_PRODUCT_FESTO_CPX_USB 0x0102 /* CPX-USB */ +#define USB_PRODUCT_FESTO_CMSP 0x0501 /* CMSP */ + +/* Fiberline products */ +#define USB_PRODUCT_FIBERLINE_WL430U 0x6003 /* WL-430U */ + +/* Fossil products */ +#define USB_PRODUCT_FOSSIL_WRISTPDA 0x0002 /* Wrist PDA */ + +/* Foxconn products */ +#define USB_PRODUCT_FOXCONN_TCOM_TC_300 0xe000 /* T-Com TC 300 */ +#define USB_PRODUCT_FOXCONN_PIRELLI_DP_L10 0xe003 /* Pirelli DP-L10 */ + +/* Freecom products */ +#define USB_PRODUCT_FREECOM_DVD 0xfc01 /* Connector for DVD drive */ + +/* Fujitsu Siemens Computers products */ +#define USB_PRODUCT_FSC_E5400 0x1009 /* PrismGT USB 2.0 WLAN */ + +/* Future Technology Devices products */ +#define USB_PRODUCT_FTDI_FT232_1 0x0232 /* Serial */ +#define USB_PRODUCT_FTDI_SERIAL_8U232AM 0x6001 /* 8U232AM Serial */ +#define USB_PRODUCT_FTDI_SERIAL_8U232AM4 0x6004 /* 8U232AM Serial */ +#define USB_PRODUCT_FTDI_FT232_3 0x6006 /* Serial */ +#define USB_PRODUCT_FTDI_FT232_4 0x6007 /* Serial */ +#define USB_PRODUCT_FTDI_FT232_5 0x6008 /* Serial */ +#define USB_PRODUCT_FTDI_FT232_6 0x6009 /* Serial */ +#define USB_PRODUCT_FTDI_SERIAL_2232C 0x6010 /* 2232C Serial */ +#define USB_PRODUCT_FTDI_FT4232H 0x6011 /* FT4232H */ +#define USB_PRODUCT_FTDI_FTX 0x6015 /* FTX */ +#define USB_PRODUCT_FTDI_PS2KBDMS 0x8371 /* PS/2 Keyboard/Mouse */ +#define USB_PRODUCT_FTDI_SERIAL_8U100AX 0x8372 /* Serial */ +#define USB_PRODUCT_FTDI_MJS_SIRIUS_PC_2 0x9379 /* MJS Sirius To PC Interface */ +#define USB_PRODUCT_FTDI_OPENRD 0x9e90 /* OpenRD JTAGKey */ +#define USB_PRODUCT_FTDI_CANDAPTER 0x9f80 /* CANdapter */ +#define USB_PRODUCT_FTDI_NXTCAM 0xabb8 /* Mindstorms NXTCam */ +#define USB_PRODUCT_FTDI_OOCDLINK 0xbaf8 /* OOCDlink */ +#define USB_PRODUCT_FTDI_LM3S_DEVEL 0xbcd8 /* LM3S Devel */ +#define USB_PRODUCT_FTDI_LM3S_EVAL 0xbcd9 /* LM3S Eval */ +#define USB_PRODUCT_FTDI_TURTELIZER_JTAG 0xbdc8 /* JTAG/RS-232 */ +#define USB_PRODUCT_FTDI_OPENDCC 0xbfd8 /* OpenDCC */ +#define USB_PRODUCT_FTDI_OPENDCC_SNIFFER 0xbfd9 /* OpenDCC Sniffer */ +#define USB_PRODUCT_FTDI_OPENDCC_THROTTLE 0xbfda /* OpenDCC Throttle */ +#define USB_PRODUCT_FTDI_OPENDCC_GATEWAY 0xbfdb /* OpenDCC Gateway */ +#define USB_PRODUCT_FTDI_LOCOBUFFER 0xc7d0 /* RR-CirKits LocoBuffer */ +#define USB_PRODUCT_FTDI_DMX4ALL 0xc850 /* DMX4ALL DMX interface */ +#define USB_PRODUCT_FTDI_ASK_RDR4X7_1 0xc990 /* ASK RDR 4X7 */ +#define USB_PRODUCT_FTDI_ASK_RDR4X7_2 0xc991 /* ASK RDR 4X7 */ +#define USB_PRODUCT_FTDI_ASK_RDR4X7_3 0xc992 /* ASK RDR 4X7 */ +#define USB_PRODUCT_FTDI_ASK_RDR4X7_4 0xc993 /* ASK RDR 4X7 */ +#define USB_PRODUCT_FTDI_ASK_RDR4X7_5 0xc994 /* ASK RDR 4X7 */ +#define USB_PRODUCT_FTDI_ASK_RDR4X7_6 0xc995 /* ASK RDR 4X7 */ +#define USB_PRODUCT_FTDI_ASK_RDR4X7_7 0xc996 /* ASK RDR 4X7 */ +#define USB_PRODUCT_FTDI_ASK_RDR4X7_8 0xc997 /* ASK RDR 4X7 */ +#define USB_PRODUCT_FTDI_MJS_SIRIUS_PC_1 0xca81 /* MJS Sirius To PC Interface */ +#define USB_PRODUCT_FTDI_CHAMELEON 0xcaa0 /* uChameleon */ +#define USB_PRODUCT_FTDI_OPENPORT_13M 0xcc48 /* OpenPort 1.3 Mitsubishi */ +#define USB_PRODUCT_FTDI_OPENPORT_13S 0xcc49 /* OpenPort 1.3 Subaru */ +#define USB_PRODUCT_FTDI_OPENPORT_13U 0xcc4a /* OpenPort 1.3 Universal */ +#define USB_PRODUCT_FTDI_SERIAL_2232L 0xcff8 /* 2232L Serial */ +#define USB_PRODUCT_FTDI_SCS_0 0xd010 /* Radio Modem */ +#define USB_PRODUCT_FTDI_SCS_1 0xd011 /* Radio Modem */ +#define USB_PRODUCT_FTDI_SCS_2 0xd012 /* Radio Modem */ +#define USB_PRODUCT_FTDI_SCS_3 0xd013 /* Radio Modem */ +#define USB_PRODUCT_FTDI_SCS_4 0xd014 /* Radio Modem */ +#define USB_PRODUCT_FTDI_SCS_5 0xd015 /* Radio Modem */ +#define USB_PRODUCT_FTDI_SCS_6 0xd016 /* Radio Modem */ +#define USB_PRODUCT_FTDI_SCS_7 0xd017 /* Radio Modem */ +#define USB_PRODUCT_FTDI_IPLUS 0xd070 /* iPlus */ +#define USB_PRODUCT_FTDI_IPLUS2 0xd071 /* iPlus */ +#define USB_PRODUCT_FTDI_XSENS_1 0xd388 /* Serial */ +#define USB_PRODUCT_FTDI_XSENS_2 0xd389 /* Serial */ +#define USB_PRODUCT_FTDI_XSENS_3 0xd38a /* Serial */ +#define USB_PRODUCT_FTDI_XSENS_4 0xd38b /* Serial */ +#define USB_PRODUCT_FTDI_XSENS_5 0xd38c /* Serial */ +#define USB_PRODUCT_FTDI_XSENS_6 0xd38d /* Serial */ +#define USB_PRODUCT_FTDI_XSENS_7 0xd38e /* Serial */ +#define USB_PRODUCT_FTDI_XSENS_8 0xd38f /* Serial */ +#define USB_PRODUCT_FTDI_GAMMASCOUT 0xd678 /* Gamma Scout Online */ +#define USB_PRODUCT_FTDI_JTAGCABLEII 0xd738 /* Propox JTAG */ +#define USB_PRODUCT_FTDI_WESTREX_777 0xdc00 /* Westrex 777 */ +#define USB_PRODUCT_FTDI_WESTREX_8900F 0xdc01 /* Westrex 8900F */ +#define USB_PRODUCT_FTDI_ACG_HFDUAL 0xdd20 /* HF Dual ISO Reader */ +#define USB_PRODUCT_FTDI_ARTEMIS 0xdf28 /* CCD camera */ +#define USB_PRODUCT_FTDI_ATK16 0xdf30 /* ATK-16 Camera */ +#define USB_PRODUCT_FTDI_ATK16HR 0xdf31 /* ATK-16HR Camera */ +#define USB_PRODUCT_FTDI_ATK16C 0xdf32 /* ATK-16C Camera */ +#define USB_PRODUCT_FTDI_ATK16HRC 0xdf33 /* ATK-16HRC Camera */ +#define USB_PRODUCT_FTDI_ATK16IC 0xdf35 /* ATK-16IC Camera */ +#define USB_PRODUCT_FTDI_ELV_USR 0xe000 /* USR */ +#define USB_PRODUCT_FTDI_ELV_MSM1 0xe001 /* Mini-Sound-Modul */ +#define USB_PRODUCT_FTDI_ELV_KL100 0xe002 /* KL 100 */ +#define USB_PRODUCT_FTDI_ELV_WS550 0xe004 /* WS 550 */ +#define USB_PRODUCT_FTDI_ELV_WS888 0xe008 /* WS 888 */ +#define USB_PRODUCT_FTDI_ELV_TWS550 0xe009 /* WS 550 */ +#define USB_PRODUCT_FTDI_ELV_FEM 0xe00a /* Funk Energie Monitor */ +#define USB_PRODUCT_FTDI_YEI_SC31 0xe050 /* ServoCenter3.1 */ +#define USB_PRODUCT_FTDI_ELV_FHZ1300PC 0xe0e8 /* FHZ 1300 PC */ +#define USB_PRODUCT_FTDI_ELV_WS500 0xe0e9 /* WS 500 */ +#define USB_PRODUCT_FTDI_ELV_HS485 0xe0ea /* RS-485 */ +#define USB_PRODUCT_FTDI_ELV_UMS100 0xe0eb /* UMS 100 */ +#define USB_PRODUCT_FTDI_ELV_TFD128 0xe0ec /* TFD 128 */ +#define USB_PRODUCT_FTDI_ELV_FM3RX 0xe0ed /* FM3 RX */ +#define USB_PRODUCT_FTDI_ELV_WS777 0xe0ee /* WS 777 */ +#define USB_PRODUCT_FTDI_ELV_EM1010PC 0xe0ef /* EM 1010 PC */ +#define USB_PRODUCT_FTDI_ELV_CSI8 0xe0f0 /* CSI 8 */ +#define USB_PRODUCT_FTDI_ELV_EM1000DL 0xe0f1 /* EM 1000 DL */ +#define USB_PRODUCT_FTDI_ELV_PCK100 0xe0f2 /* PCK 100 */ +#define USB_PRODUCT_FTDI_ELV_RFP500 0xe0f3 /* RFP 500 */ +#define USB_PRODUCT_FTDI_ELV_FS20SIG 0xe0f4 /* FS 20 SIG */ +#define USB_PRODUCT_FTDI_ELV_UTP8 0xe0f5 /* UTP 8 */ +#define USB_PRODUCT_FTDI_ELV_WS300PC 0xe0f6 /* WS 300 PC */ +#define USB_PRODUCT_FTDI_ELV_WS444PC 0xe0f7 /* WS 444 PC */ +#define USB_PRODUCT_FTDI_FISCO 0xe40b /* Serial */ +#define USB_PRODUCT_FTDI_ECO_PRO 0xe520 /* EVER Eco Pro UPS */ +#define USB_PRODUCT_FTDI_ACTROBOTS 0xe548 /* Active Robots comms */ +#define USB_PRODUCT_FTDI_PYRAMID 0xe6c8 /* Pyramid Display */ +#define USB_PRODUCT_FTDI_UNICOM 0xe700 /* Unicom III */ +#define USB_PRODUCT_FTDI_GUDE_1 0xe808 /* Serial */ +#define USB_PRODUCT_FTDI_GUDE_2 0xe809 /* Serial */ +#define USB_PRODUCT_FTDI_GUDE_3 0xe80a /* Serial */ +#define USB_PRODUCT_FTDI_GUDE_4 0xe80b /* Serial */ +#define USB_PRODUCT_FTDI_GUDE_5 0xe80c /* Serial */ +#define USB_PRODUCT_FTDI_GUDE_6 0xe80d /* Serial */ +#define USB_PRODUCT_FTDI_GUDE_7 0xe80e /* Serial */ +#define USB_PRODUCT_FTDI_GUDE_8 0xe80f /* Serial */ +#define USB_PRODUCT_FTDI_EISCOU 0xe888 /* Expert ISDN */ +#define USB_PRODUCT_FTDI_UOPTBR 0xe889 /* RS232 OptoBridge */ +#define USB_PRODUCT_FTDI_DCF 0xe88a /* Expert mouseCLOCK USB II */ +#define USB_PRODUCT_FTDI_MSF 0xe88b /* Expert mouseCLOCK USB II MSF */ +#define USB_PRODUCT_FTDI_HBG 0xe88c /* Expert mouseCLOCK USB II HBG */ +#define USB_PRODUCT_FTDI_GUDE_9 0xe88d /* Serial */ +#define USB_PRODUCT_FTDI_GUDE_A 0xe88e /* Serial */ +#define USB_PRODUCT_FTDI_GUDE_B 0xe88f /* Serial */ +#define USB_PRODUCT_FTDI_ECLO_1WIRE 0xea90 /* 1-Wire */ +#define USB_PRODUCT_FTDI_TNCX 0xebe0 /* TNC-X packet-radio */ +#define USB_PRODUCT_FTDI_TERATRONIK_VCP 0xec88 /* VCP */ +#define USB_PRODUCT_FTDI_TERATRONIK_D2XX 0xec89 /* D2XX */ +#define USB_PRODUCT_FTDI_REU_TINY 0xed22 /* RigExpert Tiny */ +#define USB_PRODUCT_FTDI_HO870 0xed71 /* HO870 */ +#define USB_PRODUCT_FTDI_HO820 0xed74 /* HO820 */ +#define USB_PRODUCT_FTDI_SERIAL_232BM 0xee18 /* FT232BM Serial */ +#define USB_PRODUCT_FTDI_MHAM_KW 0xeee8 /* KW */ +#define USB_PRODUCT_FTDI_MHAM_YS 0xeee9 /* YS */ +#define USB_PRODUCT_FTDI_MHAM_Y6 0xeeea /* Y6 */ +#define USB_PRODUCT_FTDI_MHAM_Y8 0xeeeb /* Y8 */ +#define USB_PRODUCT_FTDI_MHAM_IC 0xeeec /* IC */ +#define USB_PRODUCT_FTDI_MHAM_DB9 0xeeed /* DB9 */ +#define USB_PRODUCT_FTDI_MHAM_RS232 0xeeee /* RS232 */ +#define USB_PRODUCT_FTDI_MHAM_Y9 0xeeef /* Y9 */ +#define USB_PRODUCT_FTDI_DGQG 0xef50 /* DGQG */ +#define USB_PRODUCT_FTDI_DUSB 0xef51 /* DUSB */ +#define USB_PRODUCT_FTDI_ELV_UAD8 0xf068 /* UAD 8 */ +#define USB_PRODUCT_FTDI_ELV_UAD7 0xf069 /* UAD 7 */ +#define USB_PRODUCT_FTDI_ELV_USI2 0xf06a /* USI 2 */ +#define USB_PRODUCT_FTDI_ELV_T1100 0xf06b /* T 1100 */ +#define USB_PRODUCT_FTDI_ELV_PCD200 0xf06c /* PCD 200 */ +#define USB_PRODUCT_FTDI_ELV_ULA200 0xf06d /* ULA 200 */ +#define USB_PRODUCT_FTDI_ELV_ALC8500 0xf06e /* ALC 8500 Expert */ +#define USB_PRODUCT_FTDI_ELV_FHZ1000PC 0xf06f /* FHZ 1000 PC */ +#define USB_PRODUCT_FTDI_PERLE_UP 0xf0c0 /* UltraPort */ +#define USB_PRODUCT_FTDI_SPROG_II 0xf0c8 /* Sprog II */ +#define USB_PRODUCT_FTDI_PIEGROUP_IR 0xf208 /* Infrared */ +#define USB_PRODUCT_FTDI_ACTZWAVE 0xf2d0 /* HomePro ZWave */ +#define USB_PRODUCT_FTDI_GALAXY_1 0xf3c0 /* Serial */ +#define USB_PRODUCT_FTDI_GALAXY_2 0xf3c1 /* Serial */ +#define USB_PRODUCT_FTDI_COASTAL_TNCX 0xf448 /* Coastal ChipWorks TNC-X */ +#define USB_PRODUCT_FTDI_LINX_MASTER2 0xf449 /* Master Development 2.0 */ +#define USB_PRODUCT_FTDI_LINX_1 0xf44a /* Serial */ +#define USB_PRODUCT_FTDI_LINX_2 0xf44b /* Serial */ +#define USB_PRODUCT_FTDI_LINX_3 0xf44c /* Serial */ +#define USB_PRODUCT_FTDI_OCEANIC 0xf460 /* Oceanic instrument */ +#define USB_PRODUCT_FTDI_SUUNTO 0xf680 /* Suunto Sports */ +#define USB_PRODUCT_FTDI_USBUIRT 0xf850 /* USB-UIRT */ +#define USB_PRODUCT_FTDI_USBX_707 0xf857 /* USBX-707 */ +#define USB_PRODUCT_FTDI_CCS_ICDU20 0xf9d0 /* ICD-U20 */ +#define USB_PRODUCT_FTDI_CCS_ICDU40 0xf9d1 /* ICD-U40 */ +#define USB_PRODUCT_FTDI_CCS_MACHX 0xf9d2 /* MACH-X */ +#define USB_PRODUCT_FTDI_CCS_LOAD_N_GO 0xf9d3 /* LOAD N GO */ +#define USB_PRODUCT_FTDI_CCS_ICDU64 0xf9d4 /* ICDU64 */ +#define USB_PRODUCT_FTDI_CCS_PRIME8 0xf9d5 /* PRIME8 */ +#define USB_PRODUCT_FTDI_ITM_TOUCH 0xf9e9 /* ITM Touchscreen */ +#define USB_PRODUCT_FTDI_USBSERIAL 0xfa00 /* Matrix Orbital USB Serial */ +#define USB_PRODUCT_FTDI_LCD_MX200 0xfa01 /* Matrix Orbital MX200 Series LCD */ +#define USB_PRODUCT_FTDI_LCD_MTXO 0xfa02 /* Matrix Orbital LCD */ +#define USB_PRODUCT_FTDI_LCD_LK202_24 0xfa03 /* Matrix Orbital LK202-24 LCD */ +#define USB_PRODUCT_FTDI_LCD_LK204_24 0xfa04 /* Matrix Orbital LK204-24 LCD */ +#define USB_PRODUCT_FTDI_MATRIX_2 0xfa05 /* Matrix Orbital LCD */ +#define USB_PRODUCT_FTDI_MATRIX_3 0xfa06 /* Matrix Orbital LCD */ +#define USB_PRODUCT_FTDI_RELAIS 0xfa10 /* Relais */ +#define USB_PRODUCT_FTDI_TIRA1 0xfa78 /* Tira-1 */ +#define USB_PRODUCT_FTDI_PCDJ_DAC2 0xfa88 /* DAC-2 */ +#define USB_PRODUCT_FTDI_ACCESSO 0xfad0 /* Accesso reader */ +#define USB_PRODUCT_FTDI_THORLABS 0xfaf0 /* Serial */ +#define USB_PRODUCT_FTDI_ELV_UR100 0xfb58 /* UR 100 */ +#define USB_PRODUCT_FTDI_ELV_CLI7000 0xfb59 /* CLI 7000 */ +#define USB_PRODUCT_FTDI_ELV_UM100 0xfb5a /* UM 100 */ +#define USB_PRODUCT_FTDI_ELV_UO100 0xfb5b /* UO 100 */ +#define USB_PRODUCT_FTDI_ELV_PPS7330 0xfb5c /* PPS 7330 */ +#define USB_PRODUCT_FTDI_ELV_TFM100 0xfb5d /* TFM 100 */ +#define USB_PRODUCT_FTDI_ELV_UDF77 0xfb5e /* UDF 77 */ +#define USB_PRODUCT_FTDI_ELV_UIO88 0xfb5f /* UIO 88 */ +#define USB_PRODUCT_FTDI_R2000KU_RNG 0xfb80 /* R2000KU RNG */ +#define USB_PRODUCT_FTDI_BCS_SE923 0xfb99 /* BCS SE923 */ +#define USB_PRODUCT_FTDI_FT232RL 0xfbfa /* FT232RL */ +#define USB_PRODUCT_FTDI_LCD_CFA_632 0xfc08 /* Crystalfontz CFA-632 LCD */ +#define USB_PRODUCT_FTDI_LCD_CFA_634 0xfc09 /* Crystalfontz CFA-634 LCD */ +#define USB_PRODUCT_FTDI_LCD_CFA_547 0xfc0a /* Crystalfontz CFA-547 LCD */ +#define USB_PRODUCT_FTDI_LCD_CFA_633 0xfc0b /* Crystalfontz CFA-633 LCD */ +#define USB_PRODUCT_FTDI_LCD_CFA_631 0xfc0c /* Crystalfontz CFA-631 LCD */ +#define USB_PRODUCT_FTDI_LCD_CFA_635 0xfc0d /* Crystalfontz CFA-635 LCD */ +#define USB_PRODUCT_FTDI_LCD_CFA_640 0xfc0e /* Crystalfontz CFA-640 LCD */ +#define USB_PRODUCT_FTDI_LCD_CFA_642 0xfc0f /* Crystalfontz CFA-642 LCD */ +#define USB_PRODUCT_FTDI_IRTRANS 0xfc60 /* Serial */ +#define USB_PRODUCT_FTDI_PROTEGO_1 0xfc70 /* Protego */ +#define USB_PRODUCT_FTDI_PROTEGO_R200 0xfc71 /* R200-USB TRNG */ +#define USB_PRODUCT_FTDI_PROTEGO_3 0xfc72 /* Protego */ +#define USB_PRODUCT_FTDI_PROTEGO_4 0xfc73 /* Protego */ +#define USB_PRODUCT_FTDI_SEMC_DSS20 0xfc82 /* SEMC DSS-20 SyncStation */ +#define USB_PRODUCT_FTDI_CANVIEW 0xfd60 /* CANview */ +#define USB_PRODUCT_FTDI_VNHC 0xfe38 /* Modem */ +#define USB_PRODUCT_FTDI_AMC232 0xff00 /* AMC-232USB0 */ +#define USB_PRODUCT_FTDI_TTUSB 0xff20 /* TT-USB */ +#define USB_PRODUCT_FTDI_IBS_US485 0xff38 /* US485 */ +#define USB_PRODUCT_FTDI_IBS_PICPRO 0xff39 /* PIC-Programmer */ +#define USB_PRODUCT_FTDI_IBS_PCMCIA 0xff3a /* PCMCIA SRAM-cards reader */ +#define USB_PRODUCT_FTDI_IBS_PK1 0xff3b /* Particel counter PK1 */ +#define USB_PRODUCT_FTDI_IBS_RS232MON 0xff3c /* RS232 */ +#define USB_PRODUCT_FTDI_IBS_APP70 0xff3d /* APP 70 dust monitoring */ +#define USB_PRODUCT_FTDI_IBS_PEDO 0xff3e /* IBS PEDO-Modem */ +#define USB_PRODUCT_FTDI_IBS_1 0xff3f /* Serial */ +#define USB_PRODUCT_FTDI_CANUSB 0xffa8 /* CANUSB */ + +/* Fuji photo products */ +#define USB_PRODUCT_FUJIPHOTO_MASS0100 0x0100 /* Mass Storage */ + +/* Fujitsu products */ +#define USB_PRODUCT_FUJITSU_AH_F401U 0x105b /* AH-F401U Air H device */ + +/* Fujitsu Component products */ +#define USB_PRODUCT_FUJITSUCOMP_KEYBOARD6 0x0005 /* Type 6 Keyboard */ +#define USB_PRODUCT_FUJITSUCOMP_KEYBOARD7 0x00a2 /* Type 7 Keyboard */ +/* XXX The above is a North American PC style keyboard possibly */ +#define USB_PRODUCT_FUJITSUCOMP_MOUSE 0x0100 /* Type 6 Mouse */ +#define USB_PRODUCT_FUJITSUCOMP_FX5204PS 0x0423 /* Smart Power Strip FX-5204PS */ +#define USB_PRODUCT_FUJITSUCOMP_FX5251WB 0x042a /* Base Station FX-5251WB */ +#define USB_PRODUCT_FUJITSUCOMP_VIRTETH 0xa4a2 /* Virtual Eth Device */ + +/* Fushicai */ +#define USB_PRODUCT_FUSHICAI_USBTV007 0x3002 /* Fushicai Audio-Video Grabber */ + +/* Garmin International products */ +#define USB_PRODUCT_GARMIN_GPSMAP60CSX 0x0003 /* GPSmap 60Csx */ +#define USB_PRODUCT_GARMIN_IQUE3600 0x0004 /* Ique 3600 */ +#define USB_PRODUCT_GARMIN_DAKOTA20 0x23c0 /* Dakota 20 */ +#define USB_PRODUCT_GARMIN_GPSMAP62S 0x2459 /* GPSmap 62s */ + +/* GCT Semiconductor products */ +#define USB_PRODUCT_GCTSEMICON_INSTALL 0x7f40 /* GDM720x MASS storage mode */ + +/* Gear Head products */ +#define USB_PRODUCT_GEARHEAD_GHKB 0x0003 /* Gear Head Keyboard */ +#define USB_PRODUCT_GEARHEAD_GHKB107 0x0010 /* Gear Head 107-Key Keyboard */ + +/* GEMPLUS products */ +#define USB_PRODUCT_GEMPLUS_PROXPU 0x5501 /* Prox-PU/CU */ + +/* Genesys Logic products */ +#define USB_PRODUCT_GENESYS_GL620USB_A 0x0502 /* GL620USB-A GeneLink USB-USB Bridge */ +#define USB_PRODUCT_GENESYS_GENELINK 0x05e3 /* GeneLink Host-Host Bridge */ +#define USB_PRODUCT_GENESYS_GL650 0x0604 /* GL650 Hub */ +#define USB_PRODUCT_GENESYS_GL641USB 0x0700 /* GL641USB CompactFlash */ + +/* GIGABYTE products */ +#define USB_PRODUCT_GIGABYTE_GNBR402W 0x8002 /* GN-BR402W */ +#define USB_PRODUCT_GIGABYTE_GNWLBM101 0x8003 /* GN-WLBM101 */ +#define USB_PRODUCT_GIGABYTE_GNWBKG 0x8007 /* GN-WBKG */ +#define USB_PRODUCT_GIGABYTE_GNWB01GS 0x8008 /* GN-WB01GS */ +#define USB_PRODUCT_GIGABYTE_GNWI05GS 0x800a /* GN-WI05GS */ +#define USB_PRODUCT_GIGABYTE_RT2870_1 0x800b /* RT2870 */ +#define USB_PRODUCT_GIGABYTE_GNWB31N 0x800c /* GN-WB31N */ +#define USB_PRODUCT_GIGABYTE_GNWB32L 0x800d /* GN-WB32L */ + +/* Gigaset products */ +#define USB_PRODUCT_GIGASET_WLAN 0x0701 /* WLAN */ +#define USB_PRODUCT_GIGASET_SMCWUSBTG 0x0710 /* SMCWUSBT-G */ +#define USB_PRODUCT_GIGASET_SMCWUSBTG_NF 0x0711 /* SMCWUSBT-G */ +#define USB_PRODUCT_GIGASET_AR5523 0x0712 /* AR5523 */ +#define USB_PRODUCT_GIGASET_AR5523_NF 0x0713 /* AR5523 */ +#define USB_PRODUCT_GIGASET_RT2573 0x0722 /* RT2573 */ +#define USB_PRODUCT_GIGASET_RT3070_1 0x0740 /* RT3070 */ +#define USB_PRODUCT_GIGASET_RT3070_2 0x0744 /* RT3070 */ + +/* Global Sun Technology product */ +#define USB_PRODUCT_GLOBALSUN_AR5523_1 0x7801 /* AR5523 */ +#define USB_PRODUCT_GLOBALSUN_AR5523_1_NF 0x7802 /* AR5523 */ +#define USB_PRODUCT_GLOBALSUN_AR5523_2 0x7811 /* AR5523 */ +#define USB_PRODUCT_GLOBALSUN_AR5523_2_NF 0x7812 /* AR5523 */ + +/* Globespan products */ +#define USB_PRODUCT_GLOBESPAN_PRISM_GT_1 0x2000 /* PrismGT USB 2.0 WLAN */ +#define USB_PRODUCT_GLOBESPAN_PRISM_GT_2 0x2002 /* PrismGT USB 2.0 WLAN */ + +/* G.Mate */ +#define USB_PRODUCT_GMATE_YP3X00 0x1001 /* YP3X00 PDA */ + +/* GN Otometrics products */ +#define USB_PRODUCT_GNOTOMETRICS_AURICAL 0x0010 /* Aurical */ + +/* GoHubs products */ +#define USB_PRODUCT_GOHUBS_GOCOM232 0x1001 /* GoCOM232 Serial converter */ + +/* Good Way Technology products */ +#define USB_PRODUCT_GOODWAY_GWUSB2E 0x6200 /* GWUSB2E */ +#define USB_PRODUCT_GOODWAY_RT2573 0xc019 /* RT2573 */ + +/* Gravis products */ +#define USB_PRODUCT_GRAVIS_GAMEPADPRO 0x4001 /* GamePad Pro */ + +/* GREENHOUSE products */ +#define USB_PRODUCT_GREENHOUSE_KANA21 0x0001 /* CF-writer/MP3 Player */ + +/* Griffin Technology */ +#define USB_PRODUCT_GRIFFIN_IMATE 0x0405 /* iMate, ADB adapter */ + +/* Gude ADS */ +#define USB_PRODUCT_GUDE_DCF 0xdcf7 /* Expert mouseCLOCK USB */ + +/* Guillemot Corporation */ +#define USB_PRODUCT_GUILLEMOT_DALEADER 0xa300 /* DA Leader */ +#define USB_PRODUCT_GUILLEMOT_HWGUSB254 0xe000 /* HWGUSB2-54 WLAN */ +#define USB_PRODUCT_GUILLEMOT_HWGUSB254LB 0xe010 /* HWGUSB2-54-LB */ +#define USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP 0xe020 /* HWGUSB2-54V2-AP */ +#define USB_PRODUCT_GUILLEMOT_HWNU300 0xe030 /* HWNU-300 */ +#define USB_PRODUCT_GUILLEMOT_HWNUM300 0xe031 /* HWNUm-300 */ +#define USB_PRODUCT_GUILLEMOT_HWGUN54 0xe032 /* HWGUn-54 */ +#define USB_PRODUCT_GUILLEMOT_HWNUP150 0xe033 /* HWNUP-150 */ +#define USB_PRODUCT_GUILLEMOT_RTL8192CU 0xe035 /* RTL8192CU */ + +/* Gunze Gunze Electronics USA */ +#define USB_PRODUCT_GUNZE_TOUCHPANEL 0x0001 /* Gunze USB Touch Panel */ + +/* Hagiwara products */ +#define USB_PRODUCT_HAGIWARA_FGSM 0x0002 /* FlashGate SmartMedia */ +#define USB_PRODUCT_HAGIWARA_FGCF 0x0003 /* FlashGate CompactFlash */ +#define USB_PRODUCT_HAGIWARA_FG 0x0005 /* FlashGate */ + +/* HAILUCK Co., Ltd products */ +#define USB_PRODUCT_HAILUCK_KEYBOARD 0x001e /* Keyboard */ + +/* HAL Corporation products */ +#define USB_PRODUCT_HAL_IMR001 0x0011 /* Crossam2+USB IR commander */ + +/* Handspring, Inc. */ +#define USB_PRODUCT_HANDSPRING_VISOR 0x0100 /* Handspring Visor */ +#define USB_PRODUCT_HANDSPRING_TREO 0x0200 /* Handspring Treo */ +#define USB_PRODUCT_HANDSPRING_TREO600 0x0300 /* Handspring Treo 600 */ + +/* Hauppauge Computer Works */ +#define USB_PRODUCT_HAUPPAUGE_WINTV_USB_FM 0x4d12 /* WinTV FM */ + +/* Hawking Technologies products */ +#define USB_PRODUCT_HAWKING_RT2870_1 0x0001 /* RT2870 */ +#define USB_PRODUCT_HAWKING_RT2870_2 0x0003 /* RT2870 */ +#define USB_PRODUCT_HAWKING_HWUN2 0x0009 /* HWUN2 */ +#define USB_PRODUCT_HAWKING_HWDN2 0x000b /* HWDN2 */ +#define USB_PRODUCT_HAWKING_RT2870_3 0x0013 /* RT2870 */ +#define USB_PRODUCT_HAWKING_RTL8192SU_1 0x0015 /* RTL8192SU */ +#define USB_PRODUCT_HAWKING_RTL8192SU_2 0x0016 /* RTL8192SU */ +#define USB_PRODUCT_HAWKING_RT2870_4 0x0017 /* RT2870 */ +#define USB_PRODUCT_HAWKING_RT2870_5 0x0018 /* RT2870 */ +#define USB_PRODUCT_HAWKING_RTL8192CU 0x0019 /* RTL8192CU */ +#define USB_PRODUCT_HAWKING_RTL8192CU_2 0x0020 /* RTL8192CU */ +#define USB_PRODUCT_HAWKING_UF100 0x400c /* 10/100 Ethernet */ + +/* Hirose products */ +#define USB_PRODUCT_HIROSE_USB100 0x9601 /* USB-100 */ + +/* Hitachi, Ltd. products */ +#define USB_PRODUCT_HITACHI_DZMV100A 0x0004 /* DVD-CAM DZ-MV100A Camcorder */ + +/* Holtek Semiconductor, Inc. */ +#define USB_PRODUCT_HOLTEK_MOUSE 0x0499 /* Mouse */ + +/* HP products */ +#define USB_PRODUCT_HP_895C 0x0004 /* DeskJet 895C */ +#define USB_PRODUCT_HP_4100C 0x0101 /* Scanjet 4100C */ +#define USB_PRODUCT_HP_S20 0x0102 /* Photosmart S20 */ +#define USB_PRODUCT_HP_880C 0x0104 /* DeskJet 880C */ +#define USB_PRODUCT_HP_4200C 0x0105 /* ScanJet 4200C */ +#define USB_PRODUCT_HP_CDWRITERPLUS 0x0107 /* CD-Writer Plus */ +#define USB_PRODUCT_HP_KBDHUB 0x010c /* Multimedia Keyboard Hub */ +#define USB_PRODUCT_HP_HN210W 0x011c /* HN210W */ +#define USB_PRODUCT_HP_HPX9GP 0x0121 /* HP-x9G+ */ +#define USB_PRODUCT_HP_6200C 0x0201 /* ScanJet 6200C */ +#define USB_PRODUCT_HP_S20B 0x0202 /* PhotoSmart S20 */ +#define USB_PRODUCT_HP_815C 0x0204 /* DeskJet 815C */ +#define USB_PRODUCT_HP_3300C 0x0205 /* ScanJet 3300C */ +#define USB_PRODUCT_HP_CDW8200 0x0207 /* CD-Writer Plus 8200e */ +#define USB_PRODUCT_HP_1220C 0x0212 /* DeskJet 1220C */ +#define USB_PRODUCT_HP_810C 0x0304 /* DeskJet 810C/812C */ +#define USB_PRODUCT_HP_4300C 0x0305 /* Scanjet 4300C */ +#define USB_PRODUCT_HP_CD4E 0x0307 /* CD-Writer+ CD-4e */ +#define USB_PRODUCT_HP_G85XI 0x0311 /* OfficeJet G85xi */ +#define USB_PRODUCT_HP_1200 0x0317 /* LaserJet 1200 */ +#define USB_PRODUCT_HP_5200C 0x0401 /* Scanjet 5200C */ +#define USB_PRODUCT_HP_830C 0x0404 /* DeskJet 830C */ +#define USB_PRODUCT_HP_3400CSE 0x0405 /* ScanJet 3400cse */ +#define USB_PRODUCT_HP_885C 0x0504 /* DeskJet 885C */ +#define USB_PRODUCT_HP_1000 0x0517 /* LaserJet 1000 */ +#define USB_PRODUCT_HP_6300C 0x0601 /* Scanjet 6300C */ +#define USB_PRODUCT_HP_840C 0x0604 /* DeskJet 840c */ +#define USB_PRODUCT_HP_2200C 0x0605 /* ScanJet 2200C */ +#define USB_PRODUCT_HP_5300C 0x0701 /* Scanjet 5300C */ +#define USB_PRODUCT_HP_816C 0x0804 /* DeskJet 816C */ +#define USB_PRODUCT_HP_970CSE 0x1004 /* Deskjet 970Cse */ +#define USB_PRODUCT_HP_5400C 0x1005 /* Scanjet 5400C */ +#define USB_PRODUCT_HP_2215 0x1016 /* iPAQ 22xx/Jornada 548 */ +#define USB_PRODUCT_HP_959C 0x1104 /* Deskjet 959C */ +#define USB_PRODUCT_HP_568J 0x1116 /* Jornada 568 */ +#define USB_PRODUCT_HP_930C 0x1204 /* DeskJet 930c */ +#define USB_PRODUCT_HP_1005 0x1317 /* LaserJet 1005 */ +#define USB_PRODUCT_HP_P2000U 0x1801 /* Inkjet P-2000U */ +#define USB_PRODUCT_HP_HS2300 0x1e1d /* HS2300 */ +#define USB_PRODUCT_HP_T750 0x1f06 /* T750 UPS */ +#define USB_PRODUCT_HP_T1000 0x1f08 /* T1000 UPS */ +#define USB_PRODUCT_HP_T1500 0x1f09 /* T1500 UPS */ +#define USB_PRODUCT_HP_RT2200 0x1f0a /* R/T2200 UPS */ +#define USB_PRODUCT_HP_R1500G2 0x1fe0 /* R1500 G2 UPS */ +#define USB_PRODUCT_HP_T750G2 0x1fe1 /* T750 G2 UPS */ +#define USB_PRODUCT_HP_640C 0x2004 /* DeskJet 640c */ +#define USB_PRODUCT_HP_1020 0x2b17 /* LaserJet 1020 */ +#define USB_PRODUCT_HP_P1100 0x3102 /* Photosmart P1100 */ +#define USB_PRODUCT_HP_LD220 0x3524 /* LD220 */ +#define USB_PRODUCT_HP_1018 0x4117 /* LaserJet 1018 */ +#define USB_PRODUCT_HP_HN210E 0x811c /* HN210E Ethernet */ + +/* HP products */ +#define USB_PRODUCT_HP2_C500 0x6002 /* PhotoSmart C500 */ +#define USB_PRODUCT_HP3_RTL8188CU 0x1629 /* RTL8188CU */ + +/* HTC products */ +#define USB_PRODUCT_HTC_PPC6700MODEM 0x00cf /* PPC6700 Modem */ +#define USB_PRODUCT_HTC_SMARTPHONE 0x0a51 /* SmartPhone */ +#define USB_PRODUCT_HTC_ANDROID 0x0ffe /* Android phone */ + +/* HUAWEI products */ +#define USB_PRODUCT_HUAWEI_E618 0x1001 /* E618 HSDPA */ +#define USB_PRODUCT_HUAWEI_E220 0x1003 /* E220 HSDPA */ +#define USB_PRODUCT_HUAWEI_MOBILE 0x1008 /* Modem */ +#define USB_PRODUCT_HUAWEI_EM770W 0x1404 /* EM770W WCDMA */ +#define USB_PRODUCT_HUAWEI_E1750 0x1406 /* E1750 HSDPA */ +#define USB_PRODUCT_HUAWEI_E180 0x140c /* E180 HSDPA */ +#define USB_PRODUCT_HUAWEI_E510 0x1411 /* E510 HSDPA/DVB-T */ +#define USB_PRODUCT_HUAWEI_E181 0x1414 /* E181 HSDPA */ +#define USB_PRODUCT_HUAWEI_E1752 0x1417 /* E1752 HSDPA */ +#define USB_PRODUCT_HUAWEI_E182 0x1429 /* E182 HSDPA */ +#define USB_PRODUCT_HUAWEI_E3372 0x1442 /* E3372 LTE */ +#define USB_PRODUCT_HUAWEI_E161 0x1446 /* E161 HSDPA */ +#define USB_PRODUCT_HUAWEI_K3765 0x1465 /* K3765 HSDPA */ +#define USB_PRODUCT_HUAWEI_E1820 0x14ac /* E1820 HSDPA */ +#define USB_PRODUCT_HUAWEI_K4511 0x14b7 /* K4511 HSDPA */ +#define USB_PRODUCT_HUAWEI_K4510 0x14c5 /* K4510 HSDPA */ +#define USB_PRODUCT_HUAWEI_K3772 0x14cf /* K3772 LTE */ +#define USB_PRODUCT_HUAWEI_E353_INIT 0x14fe /* E353 Initial */ +#define USB_PRODUCT_HUAWEI_E392_INIT 0x1505 /* E392 Initial */ +#define USB_PRODUCT_HUAWEI_K3765_INIT 0x1520 /* K3765 Initial */ +#define USB_PRODUCT_HUAWEI_K3772_INIT 0x1526 /* K3772 Initial */ +#define USB_PRODUCT_HUAWEI_MU609 0x1573 /* ME906 LTE */ +#define USB_PRODUCT_HUAWEI_ME906S 0x15c1 /* ME906s LTE */ +#define USB_PRODUCT_HUAWEI_E173S 0x1c05 /* E173s HSDPA */ +#define USB_PRODUCT_HUAWEI_E173S_INIT 0x1c0b /* E173s Initial */ +#define USB_PRODUCT_HUAWEI_E303 0x1f01 /* E303 HSDPA */ + +/* Huawei 3Com products */ +#define USB_PRODUCT_HUAWEI3COM_WUB320G 0x0009 /* Aolynk WUB320g */ + +/* HUMAX products */ +#define USB_PRODUCT_HUMAX_PVRSMART 0x138c /* PVR-SMART */ + +/* Hyundai CuriTel (Audiovox, Pantech) products */ +#define USB_PRODUCT_HYUNDAI_PC5740 0x3701 /* PC5740 EVDO */ +#define USB_PRODUCT_HYUNDAI_UM175 0x3714 /* UM175 EVDO */ + +/* IBM Corporation */ +#define USB_PRODUCT_IBM_OPTTRAVELMOUSE 0x3107 /* Optical */ +#define USB_PRODUCT_IBM_OPTWHEELMOUSE 0x310b /* Wheel */ +#define USB_PRODUCT_IBM_USBCDROMDRIVE 0x4427 /* CD-ROM */ +#define USB_PRODUCT_IBM_THINKPADHUB 0x4484 /* Hub */ + +/* Icom, Inc. */ +#define USB_PRODUCT_ICOM_ID1 0x0004 /* ID-1 */ +#define USB_PRODUCT_ICOM_RP2C1 0x0009 /* ID-RP2C service 1 */ +#define USB_PRODUCT_ICOM_RP2C2 0x000a /* ID-RP2C service 2 */ +#define USB_PRODUCT_ICOM_RP2D 0x000b /* ID-RP2D */ +#define USB_PRODUCT_ICOM_RP2VT 0x000c /* ID-RP2V service T */ +#define USB_PRODUCT_ICOM_RP2VR 0x000d /* ID-RP2V service R */ +#define USB_PRODUCT_ICOM_RP4000VT 0x0010 /* ID-RP4000V service T */ +#define USB_PRODUCT_ICOM_RP4000VR 0x0011 /* ID-RP4000V service R */ +#define USB_PRODUCT_ICOM_RP2000VT 0x0012 /* ID-RP2000V service T */ +#define USB_PRODUCT_ICOM_RP2000VR 0x0013 /* ID-RP2000V service R */ + +/* iDowell products */ +#define USB_PRODUCT_IDOWELL_IDOWELL 0x0300 /* UPS */ + +/* id Quantique */ +#define USB_PRODUCT_IDQUANTIQUE_QUANTISUSB 0x0102 /* Quantis USB */ + +/* ID TECH products */ +#define USB_PRODUCT_IDTECH_SERIAL 0x0300 /* Serial */ + +/* Iiyama products */ +#define USB_PRODUCT_IIYAMA_HUB 0x0201 /* Hub */ + +/* Imation */ +#define USB_PRODUCT_IMATION_FLASHGO 0xb000 /* Flash Go! */ + +/* Inside Out Networks products */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT4 0x0001 /* EdgePort/4 RS232 */ +#define USB_PRODUCT_INSIDEOUT_HUBPORT7 0x0002 /* Hubport/7 */ +#define USB_PRODUCT_INSIDEOUT_RAPIDPORT4 0x0003 /* Rapidport/4 */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT4T 0x0004 /* Edgeport/4 RS232 */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT2 0x0005 /* Edgeport/2 RS232 */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT4I 0x0006 /* Edgeport/4 RS422 */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT2I 0x0007 /* Edgeport/2 RS422/RS485 */ +#define USB_PRODUCT_INSIDEOUT_HUBPORT4 0x0008 /* Hubport/4 */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT8HAND 0x0009 /* Hand-built Edgeport/8 */ +#define USB_PRODUCT_INSIDEOUT_MULTIMODEM 0x000a /* MultiTech version of RP/4 */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORTPPORT 0x000b /* Edgeport/(4)21 Parallel */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT421 0x000c /* Edgeport/421 Hub+RS232+Parallel */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT21 0x000d /* Edgeport/21 RS232+Parallel */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT8DC 0x000e /* 1/2 Edgeport/8 */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT8 0x000f /* Edgeport/8 */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT2DIN 0x0010 /* Edgeport/2 RS232/DIN */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT4DIN 0x0011 /* Edgeport/4 RS232/DIN */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT16DC 0x0012 /* 1/2 Edgeport/16 */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORTCOMP 0x0013 /* Edgeport Compatible */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT8I 0x0014 /* Edgeport/8 RS422 */ +#define USB_PRODUCT_INSIDEOUT_WATCHPORTH 0x0305 /* WatchPort/H */ +#define USB_PRODUCT_INSIDEOUT_MT4X56USB 0x1403 /* OEM device */ + +/* In-System products */ +#define USB_PRODUCT_INSYSTEM_F5U002 0x0002 /* Parallel */ +#define USB_PRODUCT_INSYSTEM_ATAPI 0x0031 /* ATAPI */ +#define USB_PRODUCT_INSYSTEM_IDEUSB2 0x0060 /* USB2 Storage */ +#define USB_PRODUCT_INSYSTEM_ISD110 0x0200 /* IDE ISD110 */ +#define USB_PRODUCT_INSYSTEM_ISD105 0x0202 /* IDE ISD105 */ +#define USB_PRODUCT_INSYSTEM_DRIVEV2 0x0301 /* Portable USB Harddrive V2 */ +#define USB_PRODUCT_INSYSTEM_DRIVEV2_5 0x0351 /* Portable USB Harddrive V2 */ +#define USB_PRODUCT_INSYSTEM_USBCABLE 0x081a /* USB cable */ +#define USB_PRODUCT_INSYSTEM_ADAPTERV2 0x5701 /* USB Storage Adapter V2 */ + +/* Intel products */ +#define USB_PRODUCT_INTEL_EASYPC_CAMERA 0x0110 /* EasyPC */ +#define USB_PRODUCT_INTEL_AP310 0x0200 /* AP310 AnyPoint II */ +#define USB_PRODUCT_INTEL_I2011B 0x1111 /* Wireless 2011B */ +#define USB_PRODUCT_INTEL_TESTBOARD 0x9890 /* 82930 test board */ +#define USB_PRODUCT_INTEL2_RMH_1 0x0020 /* Rate Matching Hub */ +#define USB_PRODUCT_INTEL2_RMH_2 0x0024 /* Rate Matching Hub */ +#define USB_PRODUCT_INTEL2_BLUETOOTH3 0x0025 /* Bluetooth */ +#define USB_PRODUCT_INTEL2_BLUETOOTH5 0x0026 /* Bluetooth */ +#define USB_PRODUCT_INTEL2_BLUETOOTH4 0x0029 /* Bluetooth */ +#define USB_PRODUCT_INTEL2_BLUETOOTH6 0x0032 /* Bluetooth */ +#define USB_PRODUCT_INTEL2_BLUETOOTH7 0x0033 /* Bluetooth */ +#define USB_PRODUCT_INTEL2_BLUETOOTH8 0x0035 /* Bluetooth */ +#define USB_PRODUCT_INTEL2_BLUETOOTH9 0x07da /* Bluetooth */ +#define USB_PRODUCT_INTEL2_BLUETOOTH10 0x07dc /* Bluetooth */ +#define USB_PRODUCT_INTEL2_BLUETOOTH 0x0a2a /* Bluetooth */ +#define USB_PRODUCT_INTEL2_BLUETOOTH2 0x0a2b /* Bluetooth */ +#define USB_PRODUCT_INTEL2_BLUETOOTH11 0x0aa7 /* Bluetooth */ +#define USB_PRODUCT_INTEL2_BLUETOOTH12 0x0aaa /* Bluetooth */ +#define USB_PRODUCT_INTEL2_RMH_3 0x8000 /* Rate Matching Hub */ +#define USB_PRODUCT_INTEL2_RMH_5 0x8001 /* Rate Matching Hub */ +#define USB_PRODUCT_INTEL2_RMH_7 0x8002 /* Rate Matching Hub */ +#define USB_PRODUCT_INTEL2_RMH_4 0x8008 /* Rate Matching Hub */ +#define USB_PRODUCT_INTEL2_RMH_6 0x8009 /* Rate Matching Hub */ +#define USB_PRODUCT_INTEL2_RMH_8 0x800a /* Rate Matching Hub */ + +/* InterBiometrics products */ +#define USB_PRODUCT_INTERBIO_IOBOARD 0x1002 /* IO Board */ +#define USB_PRODUCT_INTERBIO_MINIIOBOARD 0x1003 /* Mini IO Board */ +#define USB_PRODUCT_INTERBIO_MINIIOBOARD2 0x1006 /* Mini IO Board */ + +/* Intersil products */ +#define USB_PRODUCT_INTERSIL_PRISM_GT 0x1000 /* PrismGT USB 2.0 WLAN */ +#define USB_PRODUCT_INTERSIL_PRISM_2X 0x3642 /* Prism2.x WLAN */ + +/* Interpid Control Systems products */ +#define USB_PRODUCT_INTREPIDCS_VALUECAN 0x0601 /* ValueCAN */ +#define USB_PRODUCT_INTREPIDCS_NEOVI 0x0701 /* NeoVI Blue */ + +/* I/O DATA products */ +#define USB_PRODUCT_IODATA_USBSSMRW 0x0314 /* USB-SSMRW SD-card */ +#define USB_PRODUCT_IODATA_USBSDRW 0x031e /* USB-SDRW SD-card */ +#define USB_PRODUCT_IODATA_USBETT 0x0901 /* USB ET/T */ +#define USB_PRODUCT_IODATA_USBETTX 0x0904 /* USB ET/TX */ +#define USB_PRODUCT_IODATA_USBETTXS 0x0913 /* USB ET/TX-S */ +#define USB_PRODUCT_IODATA_USBWNB11A 0x0919 /* USB WN-B11 */ +#define USB_PRODUCT_IODATA_USBWNB11 0x0922 /* USB Airport WN-B11 */ +#define USB_PRODUCT_IODATA_USBWNG54US 0x0928 /* USB WN-G54/US */ +#define USB_PRODUCT_IODATA_USBWNG54US_NF 0x0929 /* USB WN-G54/US */ +#define USB_PRODUCT_IODATA_ETXUS2 0x092a /* ETX-US2 */ +#define USB_PRODUCT_IODATA_ETGUS2 0x0930 /* ETG-US2 */ +#define USB_PRODUCT_IODATA_FT232R 0x093c /* FT232R */ +#define USB_PRODUCT_IODATA_WNGDNUS2 0x093f /* WN-GDN/US2 */ +#define USB_PRODUCT_IODATA_RT3072_1 0x0944 /* RT3072 */ +#define USB_PRODUCT_IODATA_RT3072_2 0x0945 /* RT3072 */ +#define USB_PRODUCT_IODATA_RT3072_3 0x0947 /* RT3072 */ +#define USB_PRODUCT_IODATA_RT3072_4 0x0948 /* RT3072 */ +#define USB_PRODUCT_IODATA_WNG150UM 0x094c /* WN-G150UM */ +#define USB_PRODUCT_IODATA_RTL8192CU 0x0950 /* RTL8192CU */ +#define USB_PRODUCT_IODATA_USBRSAQ 0x0a03 /* RSAQ1 Serial */ +#define USB_PRODUCT_IODATA_USBRSAQ5 0x0a0e /* RSAQ5 Serial */ +#define USB_PRODUCT_IODATA2_USB2SC 0x0a09 /* USB2.0-SCSI Bridge USB2-SC */ + +/* IOI products */ +#define USB_PRODUCT_IOI_RTL8153 0x8153 /* RTL8153 */ + +/* Iomega products */ +#define USB_PRODUCT_IOMEGA_ZIP100 0x0001 /* Zip 100 */ +#define USB_PRODUCT_IOMEGA_ZIP250 0x0030 /* Zip 250 */ +#define USB_PRODUCT_IOMEGA_ZIP250_2 0x0032 /* Zip 250 */ +#define USB_PRODUCT_IOMEGA_CDRW 0x0055 /* CDRW 9602 */ + +/* iRiver products */ +#define USB_PRODUCT_IRIVER_IFP_1XX 0x1101 /* iFP-1xx */ +#define USB_PRODUCT_IRIVER_IFP_3XX 0x1103 /* iFP-3xx */ +#define USB_PRODUCT_IRIVER_IFP_5XX 0x1105 /* iFP-5xx */ + +/* Integrated System Solution Corp. */ +#define USB_PRODUCT_ISSC_KYBT100 0x1001 /* KY-BT100 Bluetooth */ + +/* iTegno products */ +#define USB_PRODUCT_ITEGNO_WM1080A 0x1080 /* WM1080A */ + +/* Jablotron products */ +#define USB_PRODUCT_JABLOTRON_PC60B 0x0001 /* PC-60B */ + +/* Jaton products */ +#define USB_PRODUCT_JATON_EDA 0x5704 /* Ethernet */ + +/* Jenoptik products */ +#define USB_PRODUCT_JENOPTIK_JD350 0x5300 /* JD 350 */ + +/* JETI Technische Instrumente GmbH products */ +#define USB_PRODUCT_JETI_SPC1201 0x04b2 /* SPECBOS 1201 */ + +/* JRC products */ +#define USB_PRODUCT_JRC_AH_J3001V_J3002V 0x0001 /* AirH\"PHONE AH-J3001V/J3002V */ + +/* JVC products */ +#define USB_PRODUCT_JVC_MP_PRX1 0x3008 /* MP-PRX1 */ +#define USB_PRODUCT_JVC_MP_XP7250_WL 0x3009 /* MP-XP7250 Builtin WLAN */ + +/* Kamstrup products */ +#define USB_PRODUCT_KAMSTRUP_OPTICALEYE 0x0001 /* Optical Eye/3-wire */ +#define USB_PRODUCT_KAMSTRUP_MBUS_250D 0x0005 /* M-Bus Master MultiPort 250D */ + +/* Kawatsu products */ +#define USB_PRODUCT_KAWATSU_MH4000P 0x0003 /* MiniHub 4000P */ +#define USB_PRODUCT_KAWATSU_KC180 0x0180 /* KC-180 IrDA */ + +/* Keisokugiken products */ +#define USB_PRODUCT_KEISOKUGIKEN_USBDAQ 0x0068 /* HKS-0200 USBDAQ */ + +/* Kensington products */ +#define USB_PRODUCT_KENSINGTON_ORBIT 0x1003 /* Orbit trackball */ +#define USB_PRODUCT_KENSINGTON_TURBOBALL 0x1005 /* TurboBall */ +#define USB_PRODUCT_KENSINGTON_ORBIT_MAC 0x1009 /* Orbit trackball for Mac */ +#define USB_PRODUCT_KENSINGTON_BT_EDR 0x105e /* Bluetooth */ +#define USB_PRODUCT_KENSINGTON_SLIMBLADE 0x2041 /* Slimblade Trackball */ +#define USB_PRODUCT_KENSINGTON_VIDEOCAM_VGA 0x5002 /* VideoCAM VGA */ + +/* Keyspan products */ +#define USB_PRODUCT_KEYSPAN_USA28_NF 0x0101 /* USA-28 serial */ +#define USB_PRODUCT_KEYSPAN_USA28X_NF 0x0102 /* USA-28X serial */ +#define USB_PRODUCT_KEYSPAN_USA19_NF 0x0103 /* USA-19 serial */ +#define USB_PRODUCT_KEYSPAN_USA18_NF 0x0104 /* USA-18 serial */ +#define USB_PRODUCT_KEYSPAN_USA18X_NF 0x0105 /* USA-18X serial */ +#define USB_PRODUCT_KEYSPAN_USA19W_NF 0x0106 /* USA-19W serial */ +#define USB_PRODUCT_KEYSPAN_USA19 0x0107 /* USA-19 serial */ +#define USB_PRODUCT_KEYSPAN_USA19W 0x0108 /* USA-19W serial */ +#define USB_PRODUCT_KEYSPAN_USA49W_NF 0x0109 /* USA-49W serial */ +#define USB_PRODUCT_KEYSPAN_USA49W 0x010a /* USA-49W serial */ +#define USB_PRODUCT_KEYSPAN_USA19QI_NF 0x010b /* USA-19QI serial */ +#define USB_PRODUCT_KEYSPAN_USA19QI 0x010c /* USA-19QI serial */ +#define USB_PRODUCT_KEYSPAN_USA19Q_NF 0x010d /* USA-19Q serial */ +#define USB_PRODUCT_KEYSPAN_USA19Q 0x010e /* USA-19Q serial */ +#define USB_PRODUCT_KEYSPAN_USA28 0x010f /* USA-28 serial */ +#define USB_PRODUCT_KEYSPAN_USA28XXB 0x0110 /* USA-28X/XB serial */ +#define USB_PRODUCT_KEYSPAN_USA18 0x0111 /* USA-18 serial */ +#define USB_PRODUCT_KEYSPAN_USA18X 0x0112 /* USA-18X serial */ +#define USB_PRODUCT_KEYSPAN_USA28XB_NF 0x0113 /* USA-28XB serial */ +#define USB_PRODUCT_KEYSPAN_USA28XA_NF 0x0114 /* USA-28XB serial */ +#define USB_PRODUCT_KEYSPAN_USA28XA 0x0115 /* USA-28XA serial */ +#define USB_PRODUCT_KEYSPAN_USA18XA_NF 0x0116 /* USA-18XA serial */ +#define USB_PRODUCT_KEYSPAN_USA18XA 0x0117 /* USA-18XA serial */ +#define USB_PRODUCT_KEYSPAN_USA19QW_NF 0x0118 /* USA-19WQ serial */ +#define USB_PRODUCT_KEYSPAN_USA19QW 0x0119 /* USA-19WQ serial */ +#define USB_PRODUCT_KEYSPAN_USA19HS 0x0121 /* USA-19HS serial */ +#define USB_PRODUCT_KEYSPAN_UIA10 0x0201 /* UIA-10 remote control */ +#define USB_PRODUCT_KEYSPAN_UIA11 0x0202 /* UIA-11 remote control */ + +/* Kingston products */ +#define USB_PRODUCT_KINGSTON_XX1 0x0008 /* Ethernet */ +#define USB_PRODUCT_KINGSTON_KNU101TX 0x000a /* KNU101TX Ethernet */ + +/* Kawasaki LSI products */ +#define USB_PRODUCT_KLSI_DUH3E10BT 0x0008 /* 10BT Ethernet */ +#define USB_PRODUCT_KLSI_DUH3E10BTN 0x0009 /* 10BT Ethernet */ + +/* Kobil Systems products */ +#define USB_PRODUCT_KOBIL_B1 0x2020 /* Konverter for B1 */ +#define USB_PRODUCT_KOBIL_KAAN 0x2021 /* Konverter for KAAN */ + +/* Kodak products */ +#define USB_PRODUCT_KODAK_DC220 0x0100 /* Digital Science DC220 */ +#define USB_PRODUCT_KODAK_DC260 0x0110 /* Digital Science DC260 */ +#define USB_PRODUCT_KODAK_DC265 0x0111 /* Digital Science DC265 */ +#define USB_PRODUCT_KODAK_DC290 0x0112 /* Digital Science DC290 */ +#define USB_PRODUCT_KODAK_DC240 0x0120 /* Digital Science DC240 */ +#define USB_PRODUCT_KODAK_DC280 0x0130 /* Digital Science DC280 */ +#define USB_PRODUCT_KODAK_DX4900 0x0550 /* EasyShare DX4900 */ + +/* Konica Corp. Products */ +#define USB_PRODUCT_KONICA_CAMERA 0x0720 /* Camera */ + +/* KYE products */ +#define USB_PRODUCT_KYE_NICHE 0x0001 /* Niche mouse */ +#define USB_PRODUCT_KYE_NETSCROLL 0x0003 /* Genius NetScroll mouse */ +#define USB_PRODUCT_KYE_FLIGHT2000 0x1004 /* Flight 2000 joystick */ +#define USB_PRODUCT_KYE_VIVIDPRO 0x2001 /* ColorPage Vivid-Pro */ + +/* Kyocera products */ +#define USB_PRODUCT_KYOCERA_AHK3001V 0x0203 /* AH-K3001V */ +#define USB_PRODUCT_KYOCERA2_KPC650 0x17da /* KPC650 EVDO */ + +/* LaCie products */ +#define USB_PRODUCT_LACIE_HD 0xa601 /* Hard Disk */ +#define USB_PRODUCT_LACIE_CDRW 0xa602 /* CD R/W */ + +/* Lake Shore products */ +#define USB_PRODUCT_LAKESHORE_M121 0x0100 /* Model 121 */ +#define USB_PRODUCT_LAKESHORE_M218A 0x0200 /* Model 218A */ +#define USB_PRODUCT_LAKESHORE_M219 0x0201 /* Model 219 */ +#define USB_PRODUCT_LAKESHORE_M233 0x0202 /* Model 233 */ +#define USB_PRODUCT_LAKESHORE_M235 0x0203 /* Model 235 */ +#define USB_PRODUCT_LAKESHORE_M335 0x0300 /* Model 335 */ +#define USB_PRODUCT_LAKESHORE_M336 0x0301 /* Model 336 */ +#define USB_PRODUCT_LAKESHORE_M350 0x0302 /* Model 350 */ +#define USB_PRODUCT_LAKESHORE_M371 0x0303 /* Model 371 */ +#define USB_PRODUCT_LAKESHORE_M411 0x0400 /* Model 411 */ +#define USB_PRODUCT_LAKESHORE_M425 0x0401 /* Model 425 */ +#define USB_PRODUCT_LAKESHORE_M455A 0x0402 /* Model 455A */ +#define USB_PRODUCT_LAKESHORE_M475A 0x0403 /* Model 475A */ +#define USB_PRODUCT_LAKESHORE_M465 0x0404 /* Model 465 */ +#define USB_PRODUCT_LAKESHORE_M625A 0x0600 /* Model 625A */ +#define USB_PRODUCT_LAKESHORE_M642A 0x0601 /* Model 642A */ +#define USB_PRODUCT_LAKESHORE_M648 0x0602 /* Model 648 */ +#define USB_PRODUCT_LAKESHORE_M737 0x0700 /* Model 737 */ +#define USB_PRODUCT_LAKESHORE_M776 0x0701 /* Model 776 */ + +/* Larsen and Brusgaard products */ +#define USB_PRODUCT_LARSENBRUSGAARD_ALTITRACK 0x0001 /* AltiTrack */ + +/* Leadtek products */ +#define USB_PRODUCT_LEADTEK_9531 0x2101 /* 9531 GPS */ + +/* Lenovo products */ +#define USB_PRODUCT_LENOVO_AX88179 0x304b /* AX88179 */ +#define USB_PRODUCT_LENOVO_ONELINKPRO 0x304f /* OneLink Pro */ +#define USB_PRODUCT_LENOVO_TABLETDOCK 0x3052 /* Tablet Dock */ +#define USB_PRODUCT_LENOVO_ONELINKPLUS 0x3054 /* OneLink+ Dock */ +#define USB_PRODUCT_LENOVO_WIGIGDOCK 0x3057 /* WiGig Dock */ +#define USB_PRODUCT_LENOVO_DOCK_ETHERNET 0x3062 /* USB-C Dock Ethernet */ +#define USB_PRODUCT_LENOVO_TB3GFXDOCK 0x3065 /* Thunderbolt 3 Graphics Dock */ +#define USB_PRODUCT_LENOVO_RTL8153B_1 0x3069 /* RTL8153B */ +#define USB_PRODUCT_LENOVO_TB3DOCKGEN2 0x3082 /* Thunderbolt 3 Dock Gen 2 */ +#define USB_PRODUCT_LENOVO_RTL8153B_2 0x3098 /* RTL8153B */ +#define USB_PRODUCT_LENOVO_RTL8153B_3 0x309b /* RTL8153B */ +#define USB_PRODUCT_LENOVO_RTL8153B_4 0x309c /* RTL8153B */ +#define USB_PRODUCT_LENOVO_RTL8153B_5 0x309d /* RTL8153B */ +#define USB_PRODUCT_LENOVO_ETHERNET 0x7203 /* USB 2.0 Ethernet */ +#define USB_PRODUCT_LENOVO_RTL8153_1 0x7205 /* RTL8153 */ +#define USB_PRODUCT_LENOVO_ONELINK 0x720a /* OneLink */ +#define USB_PRODUCT_LENOVO_RTL8153_2 0x720b /* RTL8153 */ +#define USB_PRODUCT_LENOVO_RTL8153_3 0x720c /* RTL8153 */ +#define USB_PRODUCT_LENOVO_RTL8153B_6 0x7214 /* RTL8153B */ +#define USB_PRODUCT_LENOVO_RTL8153B_7 0x721e /* RTL8153B */ +#define USB_PRODUCT_LENOVO_RTL8153B_8 0x8153 /* RTL8153B */ +#define USB_PRODUCT_LENOVO_RTL8153B_9 0xa359 /* RTL8153B */ +#define USB_PRODUCT_LENOVO_USBCDOCKGEN2 0xa387 /* USB-C Dock Gen 2 */ +#define USB_PRODUCT_LENOVO_TB3DOCK 0xa3c1 /* Thunderbolt 3 Dock */ + +/* Lexar products */ +#define USB_PRODUCT_LEXAR_JUMPSHOT 0x0001 /* jumpSHOT CompactFlash */ +#define USB_PRODUCT_LEXAR_2662WAR 0xa002 /* 2662W-AR */ + +/* Lexmark products */ +#define USB_PRODUCT_LEXMARK_S2450 0x0009 /* Optra S 2450 */ + +/* LG products */ +#define USB_PRODUCT_LG_RTL8153 0x9819 /* RTL8153 */ +#define USB_PRODUCT_LG_RTL8153B 0x9820 /* RTL8153 */ + +/* Liebert products */ +#define USB_PRODUCT_LIEBERT_UPS 0xffff /* UPS */ +#define USB_PRODUCT_LIEBERT2_PSA 0x0001 /* PowerSure PSA UPS */ + +/* Link Instruments products */ +#define USB_PRODUCT_LINKINSTRUMENTS_MSO19 0xf190 /* Link Instruments MSO-19 */ +#define USB_PRODUCT_LINKINSTRUMENTS_MSO28 0xf280 /* Link Instruments MSO-28 */ +#define USB_PRODUCT_LINKINSTRUMENTS_MSO28_2 0xf281 /* Link Instruments MSO-28 */ + +/* Linksys products */ +#define USB_PRODUCT_LINKSYS_MAUSB2 0x0105 /* Camedia MAUSB-2 */ +#define USB_PRODUCT_LINKSYS_USB10TX1 0x200c /* USB10TX */ +#define USB_PRODUCT_LINKSYS_HG20F9 0x20f9 /* HG20F9 Ethernet */ +#define USB_PRODUCT_LINKSYS_USB10T 0x2202 /* USB10T Ethernet */ +#define USB_PRODUCT_LINKSYS_USB100TX 0x2203 /* USB100TX Ethernet */ +#define USB_PRODUCT_LINKSYS_USB100H1 0x2204 /* USB100H1 Ethernet/HPNA */ +#define USB_PRODUCT_LINKSYS_USB10TA 0x2206 /* USB10TA Ethernet */ +#define USB_PRODUCT_LINKSYS_WUSB11 0x2211 /* WUSB11 802.11b */ +#define USB_PRODUCT_LINKSYS_WUSB11_25 0x2212 /* WUSB11 802.11b v2.5 */ +#define USB_PRODUCT_LINKSYS_WUSB12_11 0x2213 /* WUSB12 802.11b v1.1 */ +#define USB_PRODUCT_LINKSYS_USB10TX2 0x400b /* USB10TX */ +#define USB_PRODUCT_LINKSYS2_NWU11B 0x2219 /* NWU11B */ +#define USB_PRODUCT_LINKSYS2_USB200M 0x2226 /* USB 2.0 10/100 Ethernet controller */ +#define USB_PRODUCT_LINKSYS3_WUSB11V28 0x2233 /* WUSB11 v2.8 */ +#define USB_PRODUCT_LINKSYS3_WUSB11V30 0x2236 /* WUSB11 v3.0 */ +#define USB_PRODUCT_LINKSYS4_USB1000 0x0039 /* USB1000 */ +#define USB_PRODUCT_LINKSYS4_WUSB100 0x0070 /* WUSB100 */ +#define USB_PRODUCT_LINKSYS4_WUSB600N 0x0071 /* WUSB600N */ +#define USB_PRODUCT_LINKSYS4_WUSB54GCV2 0x0073 /* WUSB54GC v2 */ +#define USB_PRODUCT_LINKSYS4_WUSB54GCV3 0x0077 /* WUSB54GC v3 */ +#define USB_PRODUCT_LINKSYS4_RT3070 0x0078 /* RT3070 */ +#define USB_PRODUCT_LINKSYS4_WUSB600NV2 0x0079 /* WUSB600N v2 */ + +/* Lite-On Technology */ +#define USB_PRODUCT_LITEON_AR9271 0x4605 /* AR9271 */ + +/* Logitec products */ +#define USB_PRODUCT_LOGITEC_LAN_GTJU2 0x0102 /* LAN-GTJ/U2 */ +#define USB_PRODUCT_LOGITEC_LANTX 0x0105 /* LAN-TX */ +#define USB_PRODUCT_LOGITEC_RTL8187 0x010c /* RTL8187 */ +#define USB_PRODUCT_LOGITEC_RT2870_1 0x0162 /* RT2870 */ +#define USB_PRODUCT_LOGITEC_RT2870_2 0x0163 /* RT2870 */ +#define USB_PRODUCT_LOGITEC_RT2870_3 0x0164 /* RT2870 */ +#define USB_PRODUCT_LOGITEC_LANW300NU2 0x0166 /* LAN-W300N/U2 */ +#define USB_PRODUCT_LOGITEC_LANW150NU2 0x0168 /* LAN-W150N/U2 */ +#define USB_PRODUCT_LOGITEC_LANW300NU2S 0x0169 /* LAN-W300N/U2S */ + +/* Logitech products */ +#define USB_PRODUCT_LOGITECH_M2452 0x0203 /* M2452 keyboard */ +#define USB_PRODUCT_LOGITECH_M4848 0x0301 /* M4848 mouse */ +#define USB_PRODUCT_LOGITECH_PAGESCAN 0x040f /* PageScan */ +#define USB_PRODUCT_LOGITECH_QUICKCAMWEB 0x0801 /* QuickCam Web */ +#define USB_PRODUCT_LOGITECH_WEBCAMC200 0x0802 /* Webcam C200 */ +#define USB_PRODUCT_LOGITECH_WEBCAMC250 0x0804 /* Webcam C250 */ +#define USB_PRODUCT_LOGITECH_WEBCAMC500 0x0807 /* Webcam C500 */ +#define USB_PRODUCT_LOGITECH_WEBCAMPRO9000 0x0809 /* Webcam Pro 9000 */ +#define USB_PRODUCT_LOGITECH_QUICKCAMPRO 0x0810 /* QuickCam Pro */ +#define USB_PRODUCT_LOGITECH_WEBCAMC210 0x0819 /* Webcam C210 */ +#define USB_PRODUCT_LOGITECH_WEBCAMC310 0x081b /* Webcam C310 */ +#define USB_PRODUCT_LOGITECH_HDPROC910 0x0821 /* HD Pro Webcam C910 */ +#define USB_PRODUCT_LOGITECH_WEBCAMC270 0x0825 /* Webcam C270 */ +#define USB_PRODUCT_LOGITECH_QUICKCAMEXP 0x0840 /* QuickCam Express */ +#define USB_PRODUCT_LOGITECH_QUICKCAM 0x0850 /* QuickCam */ +#define USB_PRODUCT_LOGITECH_QUICKCAMNBDLX 0x08a9 /* QuickCam Notebook Deluxe */ +#define USB_PRODUCT_LOGITECH_QUICKCAMPRO3K 0x08b0 /* QuickCam Pro 3000 */ +#define USB_PRODUCT_LOGITECH_QUICKCAMNBPRO_1 0x08b1 /* QuickCam Notebook Pro */ +#define USB_PRODUCT_LOGITECH_QUICKCAMPRO4K 0x08b2 /* QuickCam Pro 4000 */ +#define USB_PRODUCT_LOGITECH_QUICKCAMZOOM 0x08b3 /* QuickCam Zoom */ +#define USB_PRODUCT_LOGITECH_QUICKCAMFUSION_1 0x08c1 /* QuickCam Fusion */ +#define USB_PRODUCT_LOGITECH_QUICKCAMORBITMP_1 0x08c2 /* QuickCam Orbit MP */ +#define USB_PRODUCT_LOGITECH_QUICKCAMNBPRO 0x08c3 /* QuickCam Notebook Pro */ +#define USB_PRODUCT_LOGITECH_QUICKCAMPRO5K_1 0x08c5 /* QuickCam Pro 5000 */ +#define USB_PRODUCT_LOGITECH_QUICKCAMOEM_1 0x08c6 /* QuickCam OEM */ +#define USB_PRODUCT_LOGITECH_QUICKCAMOEM_2 0x08c7 /* QuickCam OEM */ +#define USB_PRODUCT_LOGITECH_QUICKCAMULTVIS 0x08c9 /* QuickCam Ultra Vision */ +#define USB_PRODUCT_LOGITECH_QUICKCAMFUSION_2 0x08ca /* QuickCam Fusion */ +#define USB_PRODUCT_LOGITECH_QUICKCAMNBPRO_2 0x08cb /* QuickCam Notebook Pro */ +#define USB_PRODUCT_LOGITECH_QUICKCAMORBITMP_2 0x08cc /* QuickCam Orbit MP */ +#define USB_PRODUCT_LOGITECH_QUICKCAMPRO5K_2 0x08ce /* QuickCam Pro 5000 */ +#define USB_PRODUCT_LOGITECH_QUICKCAMPRO9K 0x0990 /* QuickCam Pro 9000 */ +#define USB_PRODUCT_LOGITECH_QUICKCAMPRONB 0x0991 /* QuickCam Pro Notebook */ +#define USB_PRODUCT_LOGITECH_QUICKCAMCOMMDLX 0x0992 /* QuickCam Communicate Deluxe */ +#define USB_PRODUCT_LOGITECH_QUICKCAMORBITAF 0x0994 /* QuickCam Orbit AF */ +#define USB_PRODUCT_LOGITECH_QUICKCAMCOMMMP 0x09a1 /* QuickCam Communicate MP */ +#define USB_PRODUCT_LOGITECH_QUICKCAME3500P 0x09a4 /* QuickCam E 3500 Plus */ +#define USB_PRODUCT_LOGITECH_QUICKCAMDLXNB 0x09c1 /* QuickCam Deluxe Notebook */ +#define USB_PRODUCT_LOGITECH_N43 0xc000 /* N43 */ +#define USB_PRODUCT_LOGITECH_N48 0xc001 /* N48 mouse */ +#define USB_PRODUCT_LOGITECH_MBA47 0xc002 /* M-BA47 mouse */ +#define USB_PRODUCT_LOGITECH_WMMOUSE 0xc004 /* WingMan Gaming Mouse */ +#define USB_PRODUCT_LOGITECH_BD58 0xc00c /* BD58 mouse */ +#define USB_PRODUCT_LOGITECH_UN58A 0xc030 /* iFeel Mouse */ +#define USB_PRODUCT_LOGITECH_WMPAD 0xc208 /* WingMan GamePad Extreme */ +#define USB_PRODUCT_LOGITECH_WMRPAD 0xc20a /* WingMan RumblePad */ +#define USB_PRODUCT_LOGITECH_WMJOY 0xc281 /* WingMan Force joystick */ +#define USB_PRODUCT_LOGITECH_WMFFGP 0xc293 /* WingMan Formula Force GP (GT-Force) */ +#define USB_PRODUCT_LOGITECH_ITOUCH 0xc303 /* iTouch Keyboard */ +#define USB_PRODUCT_LOGITECH_BB13 0xc401 /* USB-PS/2 Trackball */ +#define USB_PRODUCT_LOGITECH_BB18 0xc404 /* TrackMan Wheel */ +#define USB_PRODUCT_LOGITECH_RK53 0xc501 /* Cordless mouse */ +#define USB_PRODUCT_LOGITECH_RB6 0xc503 /* Cordless keyboard */ +#define USB_PRODUCT_LOGITECH_CDO 0xc504 /* Cordless Desktop Optical */ +#define USB_PRODUCT_LOGITECH_QUICKCAMPRO2 0xd001 /* QuickCam Pro */ + +/* Longcheer products */ +#define USB_PRODUCT_LONGCHEER_D21LCMASS 0x9401 /* Emobile D21LC Mass only mode */ +#define USB_PRODUCT_LONGCHEER_D21LC 0x9404 /* Emobile D21LC */ +#define USB_PRODUCT_LONGCHEER_510FU 0x9801 /* IIJmobile 510FU */ +#define USB_PRODUCT_LONGCHEER_510FUMASS 0x98ff /* IIJmobile 510FU Mass only mode */ + +/* Lucent products */ +#define USB_PRODUCT_LUCENT_EVALKIT 0x1001 /* USS-720 evaluation kit */ + +/* Luxshare products */ +#define USB_PRODUCT_LUXSHARE_RTL8153 0xd003 /* RTL8153 */ + +/* Macally products */ +#define USB_PRODUCT_MACALLY_MOUSE1 0x0101 /* mouse */ + +/* Marvell products */ +#define USB_PRODUCT_MARVELL_SHEEVAPLUG 0x9e8f /* SheevaPlug */ + +/* Matrix Orbital products */ +#define USB_PRODUCT_MATRIXORB_LCD_0100 0x0100 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0101 0x0101 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0102 0x0102 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0103 0x0103 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0104 0x0104 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0105 0x0105 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0106 0x0106 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0107 0x0107 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0108 0x0108 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0109 0x0109 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_010A 0x010a /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_010B 0x010b /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_010C 0x010c /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_010D 0x010d /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_010E 0x010e /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_010F 0x010f /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0110 0x0110 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0111 0x0111 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0112 0x0112 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0113 0x0113 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0114 0x0114 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0115 0x0115 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0116 0x0116 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0117 0x0117 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0118 0x0118 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0119 0x0119 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_011A 0x011a /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_011B 0x011b /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_011C 0x011c /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_011D 0x011d /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_011E 0x011e /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_011F 0x011f /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0120 0x0120 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0121 0x0121 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0122 0x0122 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0123 0x0123 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0124 0x0124 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0125 0x0125 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0126 0x0126 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0127 0x0127 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0128 0x0128 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0129 0x0129 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_012A 0x012a /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_012B 0x012b /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_012C 0x012c /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_012D 0x012d /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_012E 0x012e /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_012F 0x012f /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0130 0x0130 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0131 0x0131 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0132 0x0132 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0133 0x0133 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0134 0x0134 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0135 0x0135 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0136 0x0136 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0137 0x0137 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0138 0x0138 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0139 0x0139 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_013A 0x013a /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_013B 0x013b /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_013C 0x013c /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_013D 0x013d /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_013E 0x013e /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_013F 0x013f /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0140 0x0140 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0141 0x0141 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0142 0x0142 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0143 0x0143 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0144 0x0144 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0145 0x0145 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0146 0x0146 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0147 0x0147 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0148 0x0148 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0149 0x0149 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_014A 0x014a /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_014B 0x014b /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_014C 0x014c /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_014D 0x014d /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_014E 0x014e /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_014F 0x014f /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0150 0x0150 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0151 0x0151 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0152 0x0152 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0153 0x0153 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0154 0x0154 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0155 0x0155 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0156 0x0156 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0157 0x0157 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0158 0x0158 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0159 0x0159 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_015A 0x015a /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_015B 0x015b /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_015C 0x015c /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_015D 0x015d /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_015E 0x015e /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_015F 0x015f /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0160 0x0160 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0161 0x0161 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0162 0x0162 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0163 0x0163 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0164 0x0164 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0165 0x0165 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0166 0x0166 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0167 0x0167 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0168 0x0168 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0169 0x0169 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_016A 0x016a /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_016B 0x016b /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_016C 0x016c /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_016D 0x016d /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_016E 0x016e /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_016F 0x016f /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0170 0x0170 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0171 0x0171 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0172 0x0172 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0173 0x0173 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0174 0x0174 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0175 0x0175 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0176 0x0176 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0177 0x0177 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0178 0x0178 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0179 0x0179 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_017A 0x017a /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_017B 0x017b /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_017C 0x017c /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_017D 0x017d /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_017E 0x017e /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_017F 0x017f /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0180 0x0180 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0181 0x0181 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0182 0x0182 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0183 0x0183 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0184 0x0184 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0185 0x0185 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0186 0x0186 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0187 0x0187 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0188 0x0188 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0189 0x0189 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_018A 0x018a /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_018B 0x018b /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_018C 0x018c /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_018D 0x018d /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_018E 0x018e /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_018F 0x018f /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0190 0x0190 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0191 0x0191 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0192 0x0192 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0193 0x0193 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0194 0x0194 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0195 0x0195 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0196 0x0196 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0197 0x0197 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0198 0x0198 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_0199 0x0199 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_019A 0x019a /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_019B 0x019b /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_019C 0x019c /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_019D 0x019d /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_019E 0x019e /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_019F 0x019f /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01A0 0x01a0 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01A1 0x01a1 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01A2 0x01a2 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01A3 0x01a3 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01A4 0x01a4 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01A5 0x01a5 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01A6 0x01a6 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01A7 0x01a7 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01A8 0x01a8 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01A9 0x01a9 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01AA 0x01aa /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01AB 0x01ab /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01AC 0x01ac /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01AD 0x01ad /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01AE 0x01ae /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01AF 0x01af /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01B0 0x01b0 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01B1 0x01b1 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01B2 0x01b2 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01B3 0x01b3 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01B4 0x01b4 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01B5 0x01b5 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01B6 0x01b6 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01B7 0x01b7 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01B8 0x01b8 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01B9 0x01b9 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01BA 0x01ba /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01BB 0x01bb /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01BC 0x01bc /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01BD 0x01bd /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01BE 0x01be /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01BF 0x01bf /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01C0 0x01c0 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01C1 0x01c1 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01C2 0x01c2 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01C3 0x01c3 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01C4 0x01c4 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01C5 0x01c5 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01C6 0x01c6 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01C7 0x01c7 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01C8 0x01c8 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01C9 0x01c9 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01CA 0x01ca /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01CB 0x01cb /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01CC 0x01cc /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01CD 0x01cd /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01CE 0x01ce /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01CF 0x01cf /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01D0 0x01d0 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01D1 0x01d1 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01D2 0x01d2 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01D3 0x01d3 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01D4 0x01d4 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01D5 0x01d5 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01D6 0x01d6 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01D7 0x01d7 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01D8 0x01d8 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01D9 0x01d9 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01DA 0x01da /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01DB 0x01db /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01DC 0x01dc /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01DD 0x01dd /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01DE 0x01de /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01DF 0x01df /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01E0 0x01e0 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01E1 0x01e1 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01E2 0x01e2 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01E3 0x01e3 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01E4 0x01e4 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01E5 0x01e5 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01E6 0x01e6 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01E7 0x01e7 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01E8 0x01e8 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01E9 0x01e9 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01EA 0x01ea /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01EB 0x01eb /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01EC 0x01ec /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01ED 0x01ed /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01EE 0x01ee /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01EF 0x01ef /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01F0 0x01f0 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01F1 0x01f1 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01F2 0x01f2 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01F3 0x01f3 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01F4 0x01f4 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01F5 0x01f5 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01F6 0x01f6 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01F7 0x01f7 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01F8 0x01f8 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01F9 0x01f9 /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01FA 0x01fa /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01FB 0x01fb /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01FC 0x01fc /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01FD 0x01fd /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01FE 0x01fe /* LCD */ +#define USB_PRODUCT_MATRIXORB_LCD_01FF 0x01ff /* LCD */ + +/* MCT Corp. */ +#define USB_PRODUCT_MCT_HUB0100 0x0100 /* Hub */ +#define USB_PRODUCT_MCT_DU_H3SP_USB232 0x0200 /* D-Link DU-H3SP BAY Hub */ +#define USB_PRODUCT_MCT_USB232 0x0210 /* RS232 */ +#define USB_PRODUCT_MCT_SITECOM_USB232 0x0230 /* Sitecom RS232 */ +#define USB_PRODUCT_MCT_ML_4500 0x0302 /* ML-4500 */ + +/* MDS products */ +#define USB_PRODUCT_MDS_ISDBT 0x0001 /* MDS ISDB-T tuner */ + +/* MetaGeek tagged products */ +#define USB_PRODUCT_MECANIQUE_WISPY 0x083e /* MetaGeek Wi-Spy */ +#define USB_PRODUCT_MECANIQUE_TELLSTICK 0x0c30 /* Telldus Tellstick */ + +/* MediaTek Inc. products */ +#define USB_PRODUCT_MEDIATEK_UMASS 0x0002 /* USB MSM installer */ +#define USB_PRODUCT_MEDIATEK_DC_4COM 0x00a5 /* UMTS USB modem */ +#define USB_PRODUCT_MEDIATEK_MT7601_1 0x760a /* MT7601 */ +#define USB_PRODUCT_MEDIATEK_MT7601_2 0x760b /* MT7601 */ + +/* MEI products */ +#define USB_PRODUCT_MEI_CASHFLOW_SC 0x1100 /* Cashflow-SC */ +#define USB_PRODUCT_MEI_S2000 0x1101 /* Series 2000 */ + +/* Meinberg Funkuhren products */ +#define USB_PRODUCT_MEINBERG_USB5131 0x0301 /* USB 5131 DCF77 - Radio Clock */ +#define USB_PRODUCT_MEINBERG_DCF600USB 0x0302 /* DCF600USB - Radio Clock */ + +/* Melco, Inc products */ +#define USB_PRODUCT_MELCO_LUATX1 0x0001 /* LUA-TX Ethernet */ +#define USB_PRODUCT_MELCO_LUATX5 0x0005 /* LUA-TX Ethernet */ +#define USB_PRODUCT_MELCO_LUA2TX5 0x0009 /* LUA2-TX Ethernet */ +#define USB_PRODUCT_MELCO_LUAKTX 0x0012 /* LUA-KTX Ethernet */ +#define USB_PRODUCT_MELCO_S11 0x0016 /* WLI-USB-S11 */ +#define USB_PRODUCT_MELCO_MCRSM2 0x001b /* MCR-SM2 SmartMedia */ +#define USB_PRODUCT_MELCO_DUBPXXG 0x001c /* USB-IDE Bridge: DUB-PxxG */ +#define USB_PRODUCT_MELCO_KS11G 0x0027 /* WLI-USB-KS11G wlan */ +#define USB_PRODUCT_MELCO_LUAU2KTX 0x003d /* LUA-U2-KTX Ethernet */ +#define USB_PRODUCT_MELCO_KB11 0x0044 /* WLI-USB-KB11 WLAN */ +#define USB_PRODUCT_MELCO_KG54YB 0x005e /* WLI-U2-KG54-YB WLAN */ +#define USB_PRODUCT_MELCO_KG54 0x0066 /* WLI-U2-KG54 WLAN */ +#define USB_PRODUCT_MELCO_KG54AI 0x0067 /* WLI-U2-KG54-AI WLAN */ +#define USB_PRODUCT_MELCO_LUAU2GT 0x006e /* LUA-U2-GT Ethernet */ +#define USB_PRODUCT_MELCO_NINWIFI 0x008b /* Nintendo Wi-Fi */ +#define USB_PRODUCT_MELCO_WLIU2KAMG54 0x0091 /* WLI-U2-KAMG54 */ +#define USB_PRODUCT_MELCO_WLIU2KAMG54_NF 0x0092 /* WLI-U2-KAMG54 */ +#define USB_PRODUCT_MELCO_PCOPRS1 0x00b3 /* PC-OP-RS1 RemoteStation */ +#define USB_PRODUCT_MELCO_SG54HP 0x00d8 /* WLI-U2-SG54HP */ +#define USB_PRODUCT_MELCO_G54HP 0x00d9 /* WLI-U2-G54HP */ +#define USB_PRODUCT_MELCO_KG54L 0x00da /* WLI-U2-KG54L */ +#define USB_PRODUCT_MELCO_WLIUCG300N 0x00e8 /* WLI-UC-G300N */ +#define USB_PRODUCT_MELCO_SG54HG 0x00f4 /* WLI-U2-SG54HG */ +#define USB_PRODUCT_MELCO_WLIUCAG300N 0x012e /* WLI-UC-AG300N */ +#define USB_PRODUCT_MELCO_RT2870_1 0x0148 /* RT2870 */ +#define USB_PRODUCT_MELCO_RT2870_2 0x0150 /* RT2870 */ +#define USB_PRODUCT_MELCO_WLIUCGNHP 0x0158 /* WLI-UC-GNHP */ +#define USB_PRODUCT_MELCO_WLIUCGN 0x015d /* WLI-UC-GN */ +#define USB_PRODUCT_MELCO_WLIUCG301N 0x016f /* WLI-UC-G301N */ +#define USB_PRODUCT_MELCO_UWABR100 0x017f /* SONY UWA-BR100 */ +#define USB_PRODUCT_MELCO_WLIUCGNM 0x01a2 /* WLI-UC-GNM */ +#define USB_PRODUCT_MELCO_WLIUCGNM2 0x01ee /* WLI-UC-GNM2 */ + +/* MetaGeek products */ +#define USB_PRODUCT_METAGEEK_WISPY24I 0x2400 /* Wi-Spy 2.4i */ + +/* Metricom products */ +#define USB_PRODUCT_METRICOM_RICOCHET_GS 0x0001 /* Ricochet GS */ + +/* MGE UPS Systems products */ +#define USB_PRODUCT_MGE_UPS1 0x0001 /* UPS */ +#define USB_PRODUCT_MGE_UPS2 0xffff /* UPS */ + +/* Microchip Technology, Inc. products */ +#define USB_PRODUCT_MICROCHIP_USBLCD20X2 0x0002 /* USB-LCD-20x2 */ +#define USB_PRODUCT_MICROCHIP_USBLCD256X64 0xc002 /* USB-LCD-256x64 */ + +/* Microdia / Sonix Techonology Co., Ltd. products */ +#define USB_PRODUCT_MICRODIA_YUREX 0x1010 /* YUREX */ +#define USB_PRODUCT_MICRODIA_CAM_1 0x62c0 /* CAM_1 */ +#define USB_PRODUCT_MICRODIA_TEMPER 0x7401 /* TEMPer sensor */ +#define USB_PRODUCT_MICRODIA_TEMPERHUM 0x7402 /* TEMPerHUM sensor */ + +/* Micronet Communications products */ +#define USB_PRODUCT_MICRONET_SP128AR 0x0003 /* SP128AR EtherFast */ + +/* Microsoft products */ +#define USB_PRODUCT_MICROSOFT_SIDEPREC 0x0008 /* SideWinder Precision Pro */ +#define USB_PRODUCT_MICROSOFT_INTELLIMOUSE 0x0009 /* IntelliMouse */ +#define USB_PRODUCT_MICROSOFT_NATURALKBD 0x000b /* Natural */ +#define USB_PRODUCT_MICROSOFT_DDS80 0x0014 /* Digital Sound System 80 */ +#define USB_PRODUCT_MICROSOFT_SIDEWINDER 0x001a /* Sidewinder Precision Racing Wheel */ +#define USB_PRODUCT_MICROSOFT_INETPRO 0x001c /* Internet Keyboard Pro */ +#define USB_PRODUCT_MICROSOFT_TBEXPLORER 0x0024 /* Trackball Explorer */ +#define USB_PRODUCT_MICROSOFT_INTELLIEYE 0x0025 /* IntelliEye mouse */ +#define USB_PRODUCT_MICROSOFT_INETPRO2 0x002b /* Internet Keyboard Pro */ +#define USB_PRODUCT_MICROSOFT_MN510 0x006e /* MN510 Wireless */ +#define USB_PRODUCT_MICROSOFT_700WX 0x0079 /* Palm 700WX */ +#define USB_PRODUCT_MICROSOFT_MN110 0x007a /* 10/100 Ethernet */ +#define USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE 0x008c /* Wireless Optical IntelliMouse */ +#define USB_PRODUCT_MICROSOFT_WLNOTEBOOK 0x00b9 /* Wireless Optical Mouse (Model 1023) */ +#define USB_PRODUCT_MICROSOFT_WLNOTEBOOK3 0x00d2 /* Wireless Optical Mouse 3000 (Model 1049) */ +#define USB_PRODUCT_MICROSOFT_WLNOTEBOOK2 0x00e1 /* Wireless Optical Mouse 3000 (Model 1056) */ +#define USB_PRODUCT_MICROSOFT_XBOX360_CONTROLLER 0x028e /* XBOX 360 Controller */ +#define USB_PRODUCT_MICROSOFT_XBOX360 0x0292 /* XBOX 360 WLAN */ +#define USB_PRODUCT_MICROSOFT_WLMOBILEMOUSE3500 0x0745 /* Wireless Mobile Mouse 3500 */ +#define USB_PRODUCT_MICROSOFT_LIFECAM 0x074a /* Microsoft LifeCam */ +#define USB_PRODUCT_MICROSOFT_WLARCMOUSE 0x074f /* Wireless Arc Mouse (Model 1350) */ +#define USB_PRODUCT_MICROSOFT_DOCKETH 0x07ab /* Surface Dock Ethernet */ +#define USB_PRODUCT_MICROSOFT_DOCKETH2 0x07c6 /* Surface Dock Ethernet */ +#define USB_PRODUCT_MICROSOFT_SURFETH 0x0927 /* Surface Ethernet */ +#define USB_PRODUCT_MICROSOFT_TYPECOVER 0x096f /* Surface Go Type Cover */ +#define USB_PRODUCT_MICROSOFT_TYPECOVER2 0x09b5 /* Surface Go Type Cover */ +#define USB_PRODUCT_MICROSOFT_TYPECOVER3 0x09c0 /* Surface Pro Type Cover */ +#define USB_PRODUCT_MICROSOFT_WINDEVETH 0x0c5e + +/* Microtech products */ +#define USB_PRODUCT_MICROTECH_SCSIDB25 0x0004 /* SCSI-DB25 */ +#define USB_PRODUCT_MICROTECH_SCSIHD50 0x0005 /* SCSI-HD50 */ +#define USB_PRODUCT_MICROTECH_DPCM 0x0006 /* CameraMate */ +#define USB_PRODUCT_MICROTECH_FREECOM 0xfc01 /* Freecom IDE */ + +/* Microtek products */ +#define USB_PRODUCT_MICROTEK_336CX 0x0094 /* Phantom 336CX - C3 */ +#define USB_PRODUCT_MICROTEK_X6U 0x0099 /* ScanMaker X6 - X6U */ +#define USB_PRODUCT_MICROTEK_C6 0x009a /* Phantom C6 */ +#define USB_PRODUCT_MICROTEK_336CX2 0x00a0 /* Phantom 336CX - C3 */ +#define USB_PRODUCT_MICROTEK_V6USL 0x00a3 /* ScanMaker V6USL */ +#define USB_PRODUCT_MICROTEK_V6USL2 0x80a3 /* ScanMaker V6USL */ +#define USB_PRODUCT_MICROTEK_V6UL 0x80ac /* ScanMaker V6UL */ + +/* Midiman products */ +#define USB_PRODUCT_MIDIMAN_MIDISPORT2X2 0x1001 /* Midisport 2x2 */ + +/* Minds At Work LLC products */ +#define USB_PRODUCT_MINDSATWORK_DW 0x0001 /* Digital Wallet */ + +/* Minolta Co., Ltd. */ +#define USB_PRODUCT_MINOLTA_S304 0x4007 /* Dimage S304 */ +#define USB_PRODUCT_MINOLTA_X 0x4009 /* Dimage X */ +#define USB_PRODUCT_MINOLTA_DIMAGE7I 0x400b /* Dimage 7i */ +#define USB_PRODUCT_MINOLTA_DIMAGEA1 0x401a /* Dimage A1 */ + +/* Mitsumi products */ +#define USB_PRODUCT_MITSUMI_CDRRW 0x0000 /* CD-R/RW Drive */ +#define USB_PRODUCT_MITSUMI_MOUSE 0x6407 /* Mouse */ +#define USB_PRODUCT_MITSUMI_BLUETOOTH 0x641f /* Bluetooth */ +#define USB_PRODUCT_MITSUMI_FDD 0x6901 /* FDD */ + +/* Mobile Action products */ +#define USB_PRODUCT_MOBILEACTION_MA620 0x0620 /* MA-620 IrDA */ + +/* Mobility products */ +#define USB_PRODUCT_MOBILITY_ED200H 0x0202 /* EasiDock 200 Serial */ +#define USB_PRODUCT_MOBILITY_EA 0x0204 /* Ethernet */ +#define USB_PRODUCT_MOBILITY_EASIDOCK 0x0304 /* EasiDock Ethernet */ + +/* Modacom products */ +#define USB_PRODUCT_MODACOM_MWIMAX 0x1240 /* MODACOM Mobile wimax adaptor */ + +/* MosChip products */ +#define USB_PRODUCT_MOSCHIP_MCS7703 0x7703 /* MCS7703 Serial */ +#define USB_PRODUCT_MOSCHIP_MCS7715 0x7715 /* MCS7715 Serial Parallel */ +#define USB_PRODUCT_MOSCHIP_MCS7730 0x7730 /* MCS7730 Ethernet */ +#define USB_PRODUCT_MOSCHIP_MCS7810 0x7810 /* MCS7810 Serial */ +#define USB_PRODUCT_MOSCHIP_MCS7820 0x7820 /* MCS7820 Serial */ +#define USB_PRODUCT_MOSCHIP_MCS7830 0x7830 /* MCS7830 Ethernet */ +#define USB_PRODUCT_MOSCHIP_MCS7832 0x7832 /* MCS7832 Ethernet */ +#define USB_PRODUCT_MOSCHIP_MCS7840 0x7840 /* MCS7840 Serial */ + +/* Motorola products */ +#define USB_PRODUCT_MOTOROLA_MC141555 0x1555 /* MC141555 hub controller */ + +/* Motorola(2) products */ +#define USB_PRODUCT_MOTOROLA2_T720C 0x2822 /* T720c */ +#define USB_PRODUCT_MOTOROLA2_V360 0x4902 /* V360 */ +#define USB_PRODUCT_MOTOROLA2_USBLAN 0x600c /* USBLAN */ +#define USB_PRODUCT_MOTOROLA2_USBLAN2 0x6027 /* USBLAN */ + +/* Motorola(3) products */ +#define USB_PRODUCT_MOTOROLA3_SB4100 0x4100 /* SB4100 Cable Modem */ +#define USB_PRODUCT_MOTOROLA3_SB5100 0x5100 /* SB5100 Cable Modem */ + +/* Motorola(4) products */ +#define USB_PRODUCT_MOTOROLA4_RT2770 0x9031 /* RT2770 */ +#define USB_PRODUCT_MOTOROLA4_RT3070 0x9032 /* RT3070 */ + +/* Moxa products */ +#define USB_PRODUCT_MOXA_UPORT1110 0x1110 /* UPort 1110 */ + +/* Micro Star International products */ +#define USB_PRODUCT_MSI_WLAN 0x1020 /* WLAN */ +#define USB_PRODUCT_MSI_BLUETOOTH 0x1967 /* Bluetooth */ +#define USB_PRODUCT_MSI_RT3070_1 0x3820 /* RT3070 */ +#define USB_PRODUCT_MSI_RT3070_2 0x3821 /* RT3070 */ +#define USB_PRODUCT_MSI_RT3070_8 0x3822 /* RT3070 */ +#define USB_PRODUCT_MSI_RT3070_3 0x3870 /* RT3070 */ +#define USB_PRODUCT_MSI_RT3070_9 0x3871 /* RT3070 */ +#define USB_PRODUCT_MSI_RT2570 0x6861 /* RT2570 */ +#define USB_PRODUCT_MSI_RT2570_2 0x6865 /* RT2570 */ +#define USB_PRODUCT_MSI_RT2570_3 0x6869 /* RT2570 */ +#define USB_PRODUCT_MSI_RT2573_1 0x6874 /* RT2573 */ +#define USB_PRODUCT_MSI_RT2573_2 0x6877 /* RT2573 */ +#define USB_PRODUCT_MSI_RT3070_4 0x6899 /* RT3070 */ +#define USB_PRODUCT_MSI_RT3070_5 0x821a /* RT3070 */ +#define USB_PRODUCT_MSI_RT3070_10 0x822a /* RT3070 */ +#define USB_PRODUCT_MSI_RT3070_12 0x822b /* RT3070 */ +#define USB_PRODUCT_MSI_RT3070_13 0x822c /* RT3070 */ +#define USB_PRODUCT_MSI_RT3070_6 0x870a /* RT3070 */ +#define USB_PRODUCT_MSI_RT3070_11 0x871a /* RT3070 */ +#define USB_PRODUCT_MSI_RT3070_14 0x871b /* RT3070 */ +#define USB_PRODUCT_MSI_RT3070_15 0x871c /* RT3070 */ +#define USB_PRODUCT_MSI_RT3070_7 0x899a /* RT3070 */ +#define USB_PRODUCT_MSI_RT2573_3 0xa861 /* RT2573 */ +#define USB_PRODUCT_MSI_RT2573_4 0xa874 /* RT2573 */ +#define USB_PRODUCT_MSI_AX88772A 0xa877 /* AX88772A */ +#define USB_PRODUCT_MSI_BLUETOOTH_2 0xa970 /* Bluetooth */ +#define USB_PRODUCT_MSI_BLUETOOTH_3 0xa97a /* Bluetooth */ + +/* M-Systems products */ +#define USB_PRODUCT_MSYSTEMS_DISKONKEY 0x0010 /* DiskOnKey */ +#define USB_PRODUCT_MSYSTEMS_DISKONKEY2 0x0011 /* DiskOnKey */ + +/* MultiTech products */ +#define USB_PRODUCT_MULTITECH_ATLAS 0xf101 /* MT5634ZBA modem */ + +/* Mustek products */ +#define USB_PRODUCT_MUSTEK_1200CU 0x0001 /* 1200 CU */ +#define USB_PRODUCT_MUSTEK_600CU 0x0002 /* 600 CU */ +#define USB_PRODUCT_MUSTEK_1200USB 0x0003 /* 1200 */ +#define USB_PRODUCT_MUSTEK_1200UB 0x0006 /* 1200 UB */ +#define USB_PRODUCT_MUSTEK_1200USBPLUS 0x0007 /* 1200 Plus */ +#define USB_PRODUCT_MUSTEK_1200CUPLUS 0x0008 /* 1200 CU Plus */ +#define USB_PRODUCT_MUSTEK_BEARPAW1200F 0x0010 /* BearPaw 1200F */ +#define USB_PRODUCT_MUSTEK_600USB 0x0873 /* 600 */ +#define USB_PRODUCT_MUSTEK_MDC800 0xa800 /* MDC-800 */ +#define USB_PRODUCT_MUSTEK_DV2000 0xc441 /* DV2000 */ +#define USB_PRODUCT_MUSTEK2_PM800 0x5161 /* PowerMust 800 */ + +/* National Semiconductor */ +#define USB_PRODUCT_NATIONAL_BEARPAW1200 0x1000 /* BearPaw 1200 */ +#define USB_PRODUCT_NATIONAL_BEARPAW2400 0x1001 /* BearPaw 2400 */ + +/* NEC products */ +#define USB_PRODUCT_NEC_HUB 0x005a /* hub */ +#define USB_PRODUCT_NEC_WL300NUG 0x0249 /* WL300NU-G */ +#define USB_PRODUCT_NEC_USB2EXTEND 0x0409 /* Repeater */ +#define USB_PRODUCT_NEC_HUB_B 0x55aa /* hub */ +#define USB_PRODUCT_NEC_HUB_C 0x55ab /* hub */ +#define USB_PRODUCT_NEC_PICTY760 0xbef4 /* Picty760 */ +#define USB_PRODUCT_NEC_PICTY900 0xefbe /* Picty900 */ +#define USB_PRODUCT_NEC_PICTY920 0xf0be /* Picty920 */ +#define USB_PRODUCT_NEC_PICTY800 0xf1be /* Picty800 */ + +/* NEC2 products */ +#define USB_PRODUCT_NEC2_HUB2_0 0x0058 /* USB2.0 Hub */ + +/* NEODIO products */ +#define USB_PRODUCT_NEODIO_ND3050 0x3050 /* 6-in-1 Flash Device Controller */ +#define USB_PRODUCT_NEODIO_ND3260 0x3260 /* 8-in-1 Flash Device Controller */ +#define USB_PRODUCT_NEODIO_ND5010 0x5010 /* Multi-format Flash Controller */ + +/* NetChip Technology Products */ +#define USB_PRODUCT_NETCHIP_TURBOCONNECT 0x1080 /* Turbo-Connect */ +#define USB_PRODUCT_NETCHIP_CLIK40 0xa140 /* Clik! 40 */ +#define USB_PRODUCT_NETCHIP_ETHERNETGADGET 0xa4a2 /* EthernetGadget */ + +/* Netgear products */ +#define USB_PRODUCT_NETGEAR_EA101 0x1001 /* Ethernet */ +#define USB_PRODUCT_NETGEAR_EA101X 0x1002 /* Ethernet */ +#define USB_PRODUCT_NETGEAR_FA101 0x1020 /* 10/100 Ethernet */ +#define USB_PRODUCT_NETGEAR_FA120 0x1040 /* USB 2.0 Fast Ethernet */ +#define USB_PRODUCT_NETGEAR_M7100 0x1100 /* M7100 */ +#define USB_PRODUCT_NETGEAR_MA111NA 0x4110 /* 802.11b */ +#define USB_PRODUCT_NETGEAR_MA111V2 0x4230 /* 802.11b V2 */ +#define USB_PRODUCT_NETGEAR_WG111V2_2 0x4240 /* PrismGT USB 2.0 WLAN */ +#define USB_PRODUCT_NETGEAR_WG111V3 0x4260 /* WG111v3 */ +#define USB_PRODUCT_NETGEAR_WG111U 0x4300 /* WG111U */ +#define USB_PRODUCT_NETGEAR_WG111U_NF 0x4301 /* WG111U */ +#define USB_PRODUCT_NETGEAR_WG111V2 0x6a00 /* WG111v2 */ +#define USB_PRODUCT_NETGEAR_WN111V2 0x9001 /* WN111V2 */ +#define USB_PRODUCT_NETGEAR_WNDA3100 0x9010 /* WNDA3100 */ +#define USB_PRODUCT_NETGEAR_WNDA3200 0x9018 /* WNDA3200 */ +#define USB_PRODUCT_NETGEAR_RTL8192CU 0x9021 /* RTL8192CU */ +#define USB_PRODUCT_NETGEAR_WNA1100 0x9030 /* WNA1100 */ +#define USB_PRODUCT_NETGEAR_WNA1000 0x9040 /* WNA1000 */ +#define USB_PRODUCT_NETGEAR_WNA1000M 0x9041 /* WNA1000M */ +#define USB_PRODUCT_NETGEAR_WNA1000MV2 0x9043 /* WNA1000Mv2 */ +#define USB_PRODUCT_NETGEAR_N300MA 0xf001 /* N300MA */ + +/* Netgear(2) products */ +#define USB_PRODUCT_NETGEAR2_MA101 0x4100 /* MA101 */ +#define USB_PRODUCT_NETGEAR2_MA101B 0x4102 /* MA101 Rev B */ + +/* Netgear(3) products */ +#define USB_PRODUCT_NETGEAR3_WG111T 0x4250 /* WG111T */ +#define USB_PRODUCT_NETGEAR3_WG111T_NF 0x4251 /* WG111T */ +#define USB_PRODUCT_NETGEAR3_WG111T_1 0x4252 /* WG111T */ +#define USB_PRODUCT_NETGEAR3_WPN111 0x5f00 /* WPN111 */ +#define USB_PRODUCT_NETGEAR3_WPN111_NF 0x5f01 /* WPN111 */ + +/* Netgear(4) products */ +#define USB_PRODUCT_NETGEAR4_RTL8188CU 0x9041 /* RTL8188CU */ + +/* NetweeN products */ +#define USB_PRODUCT_NETWEEN_RTL8192CU 0x0091 /* RTL8192CU */ + +/* NHJ product */ +#define USB_PRODUCT_NHJ_CAM2 0x9120 /* Camera */ + +/* National Instruments */ +#define USB_PRODUCT_NI_GPIB_USB_A 0xc920 /* GPIB-USB-A */ + +/* Nikon products */ +#define USB_PRODUCT_NIKON_E990 0x0102 /* E990 */ +#define USB_PRODUCT_NIKON_E880 0x0103 /* E880 */ +#define USB_PRODUCT_NIKON_E885 0x0105 /* E885 */ + +/* Nokia products */ +#define USB_PRODUCT_NOKIA_CA42 0x1234 /* CA-42 Serial */ +#define USB_PRODUCT_NOKIA2_CS15UMASS 0x0610 /* Internet Stick CS-15 (umass mode) */ +#define USB_PRODUCT_NOKIA2_CS15 0x0612 /* Internet Stick CS-15 */ + +/* Noritake itron corp products */ +#define USB_PRODUCT_NORITAKE_COMEMO 0x11c0 /* Noritake COMEMO */ + +/* Nova Tech products */ +#define USB_PRODUCT_NOVATECH_NV902W 0x9020 /* NV-902W */ +#define USB_PRODUCT_NOVATECH_RT2573 0x9021 /* RT2573 */ +#define USB_PRODUCT_NOVATECH_RTL8188CU 0x9071 /* RTL8188CU */ + +/* Novatel Wireless products */ +#define USB_PRODUCT_NOVATEL_EXPRESSCARD 0x1100 /* ExpressCard 3G */ +#define USB_PRODUCT_NOVATEL_MERLINV620 0x1110 /* V620 */ +#define USB_PRODUCT_NOVATEL_MERLINV740 0x1120 /* V740 */ +#define USB_PRODUCT_NOVATEL_V720 0x1130 /* V720 */ +#define USB_PRODUCT_NOVATEL_MERLINU740 0x1400 /* U740 */ +#define USB_PRODUCT_NOVATEL_MERLINU740_2 0x1410 /* U740 */ +#define USB_PRODUCT_NOVATEL_U870 0x1420 /* U870 */ +#define USB_PRODUCT_NOVATEL_XU870 0x1430 /* XU870 */ +#define USB_PRODUCT_NOVATEL_X950D 0x1450 /* X950D */ +#define USB_PRODUCT_NOVATEL_ES620 0x2100 /* ES620 CDMA */ +#define USB_PRODUCT_NOVATEL_U720 0x2110 /* U720 */ +#define USB_PRODUCT_NOVATEL_EU870D 0x2420 /* EU870D */ +#define USB_PRODUCT_NOVATEL_U727 0x4100 /* U727 */ +#define USB_PRODUCT_NOVATEL_MC950D 0x4400 /* MC950D HSUPA */ +#define USB_PRODUCT_NOVATEL_MERLINX950D 0x5010 /* X950D */ +#define USB_PRODUCT_NOVATEL_ZEROCD2 0x5030 /* ZeroCD */ +#define USB_PRODUCT_NOVATEL_MC760CD 0x5031 /* MC760 CD */ +#define USB_PRODUCT_NOVATEL_U760 0x6000 /* U760 */ +#define USB_PRODUCT_NOVATEL_MC760 0x6002 /* MC760 */ + +/* Novatel Wireless(1) products */ +#define USB_PRODUCT_NOVATEL1_FLEXPACKGPS 0x0100 /* NovAtel FlexPack GPS */ + +/* NVIDIA products */ +#define USB_PRODUCT_NVIDIA_TEGRAETH 0x09ff /* Tegra Ethernet */ + +/* O2 Micro products */ +#define USB_PRODUCT_O2MICRO_OZ776HUB 0x7761 /* OZ776 Hub */ + +/* Omnidirectional Control Technology products */ +#define USB_PRODUCT_OCT_USBTOETHER 0x0109 /* Ethernet */ +#define USB_PRODUCT_OCT_US2308 0x0421 /* Serial */ + +/* Olimex products */ +#define USB_PRODUCT_OLIMEX_OPENOCD_JTAG 0x0003 /* OpenOCD JTAG */ + +/* Olympus products */ +#define USB_PRODUCT_OLYMPUS_C1 0x0102 /* C-1 */ +#define USB_PRODUCT_OLYMPUS_C700 0x0105 /* C-700 Ultra Zoom */ + +/* OmniVision Technologies, Inc. products */ +#define USB_PRODUCT_OMNIVISION_OV511 0x0511 /* OV511 */ +#define USB_PRODUCT_OMNIVISION_OV511PLUS 0xa511 /* OV511+ */ + +/* OMRON products */ +#define USB_PRODUCT_OMRON_BX50F 0x0057 /* BX50F UPS */ +#define USB_PRODUCT_OMRON_BX35F 0x0058 /* BX35F UPS */ +#define USB_PRODUCT_OMRON_BY35S 0x0080 /* BY35S UPS */ + +/* OnSpec Electronic, Inc. */ +#define USB_PRODUCT_ONSPEC_MD2 0x0103 /* disk */ +#define USB_PRODUCT_ONSPEC_MDCFEB 0xa000 /* MDCFE-B CF */ +#define USB_PRODUCT_ONSPEC_SIIGMS 0xa001 /* Memory Stick+CF */ +#define USB_PRODUCT_ONSPEC_DATAFAB3 0xa003 /* Datafab-based */ +#define USB_PRODUCT_ONSPEC_DATAFAB4 0xa004 /* Datafab-based */ +#define USB_PRODUCT_ONSPEC_PNYCFSM 0xa005 /* PNY/Datafab CF+SM */ +#define USB_PRODUCT_ONSPEC_STECHCFSM 0xa006 /* Simple Tech/Datafab CF+SM */ +#define USB_PRODUCT_ONSPEC_LC1 0xa109 /* CF + SM Combo (LC1) */ +#define USB_PRODUCT_ONSPEC_MD1II 0xb006 /* Datafab MD1-II PC-Card */ + +/* OnSpec Electronic, Inc.(2) */ +#define USB_PRODUCT_ONSPEC2_8IN2 0xb012 /* 8In2 */ + +/* OpenMoko products */ +#define USB_PRODUCT_OPENMOKO_N1793D 0x5118 /* Neo1973 Debug */ + +/* + * OpenMoko permits other open hardware products to use their + * product ID allocations + */ +#define USB_PRODUCT_OPENMOKO2_ONERNG 0x6086 /* Moonbase Otago OneRNG */ +#define USB_PRODUCT_OPENMOKO2_CHAOSKEY 0x60c6 /* Altusmetrum ChaosKey 1.0 */ + +/* Option products */ +#define USB_PRODUCT_OPTION_VODAFONEMC3G 0x5000 /* Vodafone Mobile Connect 3G */ +#define USB_PRODUCT_OPTION_GT3GFUSION 0x6000 /* GlobeTrotter 3G FUSION */ +#define USB_PRODUCT_OPTION_GT3GQUAD 0x6300 /* GlobeTrotter 3G QUAD */ +#define USB_PRODUCT_OPTION_GT3GQUADPLUS 0x6600 /* GlobeTrotter 3G QUAD PLUS */ +#define USB_PRODUCT_OPTION_GTMAX36 0x6701 /* GlobeTrotter MAX 3.6/7.2 */ +#define USB_PRODUCT_OPTION_GT3GPLUS 0x6721 /* GlobeTrotter 3G PLUS */ +#define USB_PRODUCT_OPTION_SCORPION 0x6901 /* GlobeTrotter HSDPA Modem */ +#define USB_PRODUCT_OPTION_GSICON72 0x6911 /* GlobeSurfer iCON 7.2 */ +#define USB_PRODUCT_OPTION_ICON225 0x6971 /* iCON 225 */ +#define USB_PRODUCT_OPTION_GTHSUPA380E 0x7211 /* GlobeTrotter HSUPA 380E */ +#define USB_PRODUCT_OPTION_ICON322 0xd033 /* iCON 322 */ +#define USB_PRODUCT_OPTION_ICON505 0xd055 /* iCON 505 */ + +/* OQO */ +#define USB_PRODUCT_OQO_WIFI01 0x0002 /* model 01 WiFi */ +#define USB_PRODUCT_OQO_BT01 0x0003 /* model 01 Bluetooth */ +#define USB_PRODUCT_OQO_ETHER01PLUS 0x7720 /* model 01+ Ethernet */ +#define USB_PRODUCT_OQO_ETHER01 0x8150 /* model 01 Ethernet */ + +/* Oregon Scientific */ +#define USB_PRODUCT_OREGONSCI_OWL_CM160 0xca05 /* OWL CM-160 */ + +/* Ours Technology Inc. */ +#define USB_PRODUCT_OTI_SOLID 0x6803 /* Solid state disk */ +#define USB_PRODUCT_OTI_DKU5 0x6858 /* DKU-5 Serial */ + +/* OvisLink product */ +#define USB_PRODUCT_OVISLINK_RT3071 0x3071 /* RT3071 */ +#define USB_PRODUCT_OVISLINK_RT3072 0x3072 /* RT3072 */ + +/* Owen.ru products */ +#define USB_PRODUCT_OWEN_AC4 0x0004 /* AC4 USB-RS485 */ + +/* Palm Computing, Inc. product */ +#define USB_PRODUCT_PALM_M500 0x0001 /* Palm m500 */ +#define USB_PRODUCT_PALM_M505 0x0002 /* Palm m505 */ +#define USB_PRODUCT_PALM_M515 0x0003 /* Palm m515 */ +#define USB_PRODUCT_PALM_I705 0x0020 /* Palm i705 */ +#define USB_PRODUCT_PALM_TUNGSTEN_Z 0x0031 /* Palm Tungsten Z */ +#define USB_PRODUCT_PALM_M125 0x0040 /* Palm m125 */ +#define USB_PRODUCT_PALM_M130 0x0050 /* Palm m130 */ +#define USB_PRODUCT_PALM_TUNGSTEN_T 0x0060 /* Palm Tungsten T */ +#define USB_PRODUCT_PALM_ZIRE_31 0x0061 /* Palm Zire 31 */ +#define USB_PRODUCT_PALM_ZIRE 0x0070 /* Palm Zire */ +#define USB_PRODUCT_PALM_SERIAL 0x0080 /* USB Serial Adaptor */ + +/* Panasonic products */ +#define USB_PRODUCT_PANASONIC_LS120 0x0901 /* LS-120 */ +#define USB_PRODUCT_PANASONIC_SDCAAE 0x1b00 /* MultiMediaCard */ +#define USB_PRODUCT_PANASONIC_TYTP50P6S 0x3900 /* TY-TP50P6-S 50in Touch Panel */ +#define USB_PRODUCT_PANASONIC_N5HBZ0000055 0x3904 /* UB94 */ + +/* Papouch products */ +#define USB_PRODUCT_PAPOUCH_SB485_1 0x0100 /* SB485 USB-485/422 */ +#define USB_PRODUCT_PAPOUCH_AP485_1 0x0101 /* AP485 USB-RS485 */ +#define USB_PRODUCT_PAPOUCH_SB422_1 0x0102 /* SB422 USB-RS422 */ +#define USB_PRODUCT_PAPOUCH_SB485_2 0x0103 /* SB485 USB-485/422 */ +#define USB_PRODUCT_PAPOUCH_AP485_2 0x0104 /* AP485 USB-RS485 */ +#define USB_PRODUCT_PAPOUCH_SB422_2 0x0105 /* SB422 USB-RS422 */ +#define USB_PRODUCT_PAPOUCH_SB485S 0x0106 /* SB485S USB-485/422 */ +#define USB_PRODUCT_PAPOUCH_SB485C 0x0107 /* SB485C USB-485/422 */ +#define USB_PRODUCT_PAPOUCH_SERIAL 0x0200 /* Serial */ +#define USB_PRODUCT_PAPOUCH_LEC 0x0300 /* Serial */ +#define USB_PRODUCT_PAPOUCH_SB232 0x0301 /* SB232 USB-RS232 */ +#define USB_PRODUCT_PAPOUCH_TMU 0x0400 /* TMU Thermometer */ +#define USB_PRODUCT_PAPOUCH_IRAMP 0x0500 /* IRAmp Duplex */ +#define USB_PRODUCT_PAPOUCH_DRAK5 0x0700 /* DRAK5 */ +#define USB_PRODUCT_PAPOUCH_QUIDO88 0x0800 /* QUIDO USB 8/8 */ +#define USB_PRODUCT_PAPOUCH_QUIDO44 0x0900 /* QUIDO USB 4/4 */ +#define USB_PRODUCT_PAPOUCH_QUIDO22 0x0a00 /* QUIDO USB 2/2 */ +#define USB_PRODUCT_PAPOUCH_QUIDO101 0x0b00 /* QUIDO USB 10/1 */ +#define USB_PRODUCT_PAPOUCH_QUIDO303 0x0c00 /* QUIDO USB 30/3 */ +#define USB_PRODUCT_PAPOUCH_QUIDO603 0x0d00 /* QUIDO USB 60(100)/3 */ +#define USB_PRODUCT_PAPOUCH_QUIDO216 0x0e00 /* QUIDO USB 2/16 */ +#define USB_PRODUCT_PAPOUCH_QUIDO332 0x0f00 /* QUIDO USB 3/32 */ +#define USB_PRODUCT_PAPOUCH_DRAK6 0x1000 /* DRAK6 USB */ +#define USB_PRODUCT_PAPOUCH_STAVOVY 0x8000 /* UPS-USB Stavovy */ +#define USB_PRODUCT_PAPOUCH_MUC 0x8001 /* MU Controller */ +#define USB_PRODUCT_PAPOUCH_SIMUKEY 0x8002 /* SimuKey */ +#define USB_PRODUCT_PAPOUCH_AD4USB 0x8003 /* AD4USB */ +#define USB_PRODUCT_PAPOUCH_GOLIATH_MUX 0x8004 /* GOLIATH MUX */ +#define USB_PRODUCT_PAPOUCH_GOLIATH_MSR 0x8005 /* GOLIATH MSR */ + +/* PARA Industrial products */ +#define USB_PRODUCT_PARA_RT3070 0x8888 /* RT3070 */ + +/* PC Sensors products */ +#define USB_PRODUCT_PCSENSORS_TEMPER 0x2107 /* TEMPer sensor */ + +/* Pegatron products */ +#define USB_PRODUCT_PEGATRON_RT2870 0x0002 /* RT2870 */ +#define USB_PRODUCT_PEGATRON_RT3070 0x000c /* RT3070 */ +#define USB_PRODUCT_PEGATRON_RT3070_2 0x000e /* RT3070 */ +#define USB_PRODUCT_PEGATRON_RT3070_3 0x0010 /* RT3070 */ +#define USB_PRODUCT_PEGATRON_RT3072 0x0011 /* RT3072 */ + +/* Pen Driver */ +#define USB_PRODUCT_PEN_USBREADER 0x0240 /* 6 in 1 */ +#define USB_PRODUCT_PEN_MOBILEDRIVE 0x0280 /* 3 in 1 */ +#define USB_PRODUCT_PEN_USBDISK 0x0d7d /* Disk */ + +/* Peracom products */ +#define USB_PRODUCT_PERACOM_SERIAL1 0x0001 /* Serial Converter */ +#define USB_PRODUCT_PERACOM_ENET 0x0002 /* Ethernet */ +#define USB_PRODUCT_PERACOM_ENET3 0x0003 /* At-Home Ethernet */ +#define USB_PRODUCT_PERACOM_ENET2 0x0005 /* Ethernet */ + +/* Pheenet products */ +#define USB_PRODUCT_PHEENET_WM168B 0x168b /* WM-168b */ +#define USB_PRODUCT_PHEENET_WL503IA 0x4017 /* WL-503IA */ +#define USB_PRODUCT_PHEENET_GWU513 0x4025 /* GWU513 */ + +/* Phidgets products */ +#define USB_PRODUCT_PHIDGETS_2X2 0x0036 /* 2x2 Interface Kit */ + +/* Philips products */ +#define USB_PRODUCT_PHILIPS_DSS350 0x0101 /* DSS 350 Digital Speaker System */ +#define USB_PRODUCT_PHILIPS_DSS 0x0104 /* DSS XXX Digital Speaker System */ +#define USB_PRODUCT_PHILIPS_HUB 0x0201 /* hub */ +#define USB_PRODUCT_PHILIPS_PCA645VC 0x0302 /* PCA645VC */ +#define USB_PRODUCT_PHILIPS_PCA646VC 0x0303 /* PCA646VC */ +#define USB_PRODUCT_PHILIPS_PCVC675K 0x0307 /* PCVC675K Vesta */ +#define USB_PRODUCT_PHILIPS_PCVC680K 0x0308 /* PCVC680K Vesta Pro */ +#define USB_PRODUCT_PHILIPS_PCVC690K 0x030c /* PCVC690K Vesta Pro Scan Camera */ +#define USB_PRODUCT_PHILIPS_PCVC730K 0x0310 /* PCVC730K ToUCam Fun */ +#define USB_PRODUCT_PHILIPS_PCVC740K 0x0311 /* PCVC740K ToUCam Pro PC */ +#define USB_PRODUCT_PHILIPS_PCVC750K 0x0312 /* PCVC750K ToUCam Pro Scan */ +#define USB_PRODUCT_PHILIPS_DSS150 0x0471 /* DSS 150 Digital Speaker System */ +#define USB_PRODUCT_PHILIPS_ACE1001 0x066a /* AKTAKOM ACE-1001 */ +#define USB_PRODUCT_PHILIPS_CPWUA054 0x1230 /* CPWUA054 */ +#define USB_PRODUCT_PHILIPS_SNU6500 0x1232 /* SNU6500 */ +#define USB_PRODUCT_PHILIPS_SNU6500_NF 0x1233 /* SNU6500 */ +#define USB_PRODUCT_PHILIPS_SNU5600 0x1236 /* SNU5600 */ +#define USB_PRODUCT_PHILIPS_SNU5630NS05 0x1237 /* SNU5630NS/05 */ +#define USB_PRODUCT_PHILIPS_DIVAUSB 0x1801 /* DIVA mp3 player */ +#define USB_PRODUCT_PHILIPS_RT2870 0x200f /* RT2870 */ + +/* Philips Semiconductor products */ +#define USB_PRODUCT_PHILIPSSEMI_HUB1122 0x1122 /* hub */ + +/* P.I. Engineering products */ +#define USB_PRODUCT_PIENGINEERING_PS2USB 0x020b /* PS2 to Mac */ +#define USB_PRODUCT_PIENGINEERING_XKEYS 0x0233 /* Xkeys Programmable Keyboard */ + +/* Pilotech Systems Co., Ltd products */ +#define USB_PRODUCT_PILOTECH_CRW600 0x0001 /* CRW-600 6-in-1 */ + +/* Pioneer DJ products */ +#define USB_PRODUCT_PIONEERDJ_RTL8152B 0x0007 /* RTL8152B */ +#define USB_PRODUCT_PIONEERDJ_RTL8153B 0x0031 /* RTL8153B */ + +/* Planex Communications products */ +#define USB_PRODUCT_PLANEX_GW_US11H 0x14ea /* GW-US11H WLAN */ +#define USB_PRODUCT_PLANEX2_RTL8188CUS 0x1201 /* RTL8188CUS */ +#define USB_PRODUCT_PLANEX2_GW_US11S 0x3220 /* GW-US11S WLAN */ +#define USB_PRODUCT_PLANEX2_RTL8188CU_3 0x4902 /* RTL8188CU */ +#define USB_PRODUCT_PLANEX2_GW_US54GXS 0x5303 /* GW-US54GXS WLAN */ +#define USB_PRODUCT_PLANEX2_GW_US300 0x5304 /* GW-US300 */ +#define USB_PRODUCT_PLANEX2_GWUS54HP 0xab01 /* GW-US54HP */ +#define USB_PRODUCT_PLANEX2_GWUS300MINIS 0xab24 /* GW-US300MiniS */ +#define USB_PRODUCT_PLANEX2_RT3070 0xab25 /* RT3070 */ +#define USB_PRODUCT_PLANEX2_GWUSNANO 0xab28 /* GW-USNano */ +#define USB_PRODUCT_PLANEX2_GWUSMICRO300 0xab29 /* GW-USMicro300 */ +#define USB_PRODUCT_PLANEX2_RTL8188CU_1 0xab2a /* RTL8188CU */ +#define USB_PRODUCT_PLANEX2_RTL8192CU 0xab2b /* RTL8192CU */ +#define USB_PRODUCT_PLANEX2_RTL8188CU_4 0xab2e /* RTL8188CU */ +#define USB_PRODUCT_PLANEX2_GWUS54MINI2 0xab50 /* GW-US54Mini2 */ +#define USB_PRODUCT_PLANEX2_GWUS54SG 0xc002 /* GW-US54SG */ +#define USB_PRODUCT_PLANEX2_GWUS54GZL 0xc007 /* GW-US54GZL */ +#define USB_PRODUCT_PLANEX2_GWUS54GD 0xed01 /* GW-US54GD */ +#define USB_PRODUCT_PLANEX2_GWUSMM 0xed02 /* GW-USMM */ +#define USB_PRODUCT_PLANEX2_RT2870 0xed06 /* RT2870 */ +#define USB_PRODUCT_PLANEX2_GWUSMICRON 0xed14 /* GW-USMicroN */ +#define USB_PRODUCT_PLANEX2_GWUSMICRON2W 0xed16 /* GW-USMicroN2W */ +#define USB_PRODUCT_PLANEX2_RTL8188CU_2 0xed17 /* RTL8188CU */ +#define USB_PRODUCT_PLANEX3_GWUS54GZ 0xab10 /* GW-US54GZ */ +#define USB_PRODUCT_PLANEX3_GU1000T 0xab11 /* GU-1000T */ +#define USB_PRODUCT_PLANEX3_GWUS54MINI 0xab13 /* GW-US54Mini */ +#define USB_PRODUCT_PLANEX4_GWUS54ZGL 0x5301 /* GW-US54ZGL */ +#define USB_PRODUCT_PLANEX4_ZD1211B 0x5302 /* ZD1211B */ + +/* Plantronics products */ +#define USB_PRODUCT_PLANTRONICS_HEADSET 0x0ca1 /* DSP-400 Headset */ + +/* PLX products */ +#define USB_PRODUCT_PLX_TESTBOARD 0x9060 /* test board */ +#define USB_PRODUCT_PLX_CA42 0xac70 /* CA-42 Serial */ + +/* PortGear products */ +#define USB_PRODUCT_PORTGEAR_EA8 0x0008 /* Ethernet */ +#define USB_PRODUCT_PORTGEAR_EA9 0x0009 /* Ethernet */ + +/* Portsmith products */ +#define USB_PRODUCT_PORTSMITH_EEA 0x3003 /* Express Ethernet */ + +/* Posiflex Technologies products */ +#define USB_PRODUCT_POSIFLEX_PP7000_1 0x0300 /* PP7000 series printer */ +#define USB_PRODUCT_POSIFLEX_PP7000_2 0x0400 /* PP7000 series printer */ + +/* PQI products */ +#define USB_PRODUCT_PQI_TRAVELFLASH 0x0001 /* Travel Flash Drive */ + +/* Primax products */ +#define USB_PRODUCT_PRIMAX_G2X300 0x0300 /* G2-200 */ +#define USB_PRODUCT_PRIMAX_G2E300 0x0301 /* G2E-300 */ +#define USB_PRODUCT_PRIMAX_G2300 0x0302 /* G2-300 */ +#define USB_PRODUCT_PRIMAX_G2E3002 0x0303 /* G2E-300 */ +#define USB_PRODUCT_PRIMAX_9600 0x0340 /* Colorado 9600 */ +#define USB_PRODUCT_PRIMAX_600U 0x0341 /* Colorado 600u */ +#define USB_PRODUCT_PRIMAX_6200 0x0345 /* Visioneer 6200 */ +#define USB_PRODUCT_PRIMAX_19200 0x0360 /* Colorado 19200 */ +#define USB_PRODUCT_PRIMAX_1200U 0x0361 /* Colorado 1200u */ +#define USB_PRODUCT_PRIMAX_G600 0x0380 /* G2-600 */ +#define USB_PRODUCT_PRIMAX_636I 0x0381 /* ReadyScan 636i */ +#define USB_PRODUCT_PRIMAX_G2600 0x0382 /* G2-600 */ +#define USB_PRODUCT_PRIMAX_G2E600 0x0383 /* G2E-600 */ +#define USB_PRODUCT_PRIMAX_COMFORT 0x4d01 /* Comfort */ +#define USB_PRODUCT_PRIMAX_MOUSEINABOX 0x4d02 /* Mouse-in-a-Box */ +#define USB_PRODUCT_PRIMAX_PCGAUMS1 0x4d04 /* Sony PCGA-UMS1 */ + +/* Prolific products */ +#define USB_PRODUCT_PROLIFIC_PL2301 0x0000 /* PL2301 Host-Host */ +#define USB_PRODUCT_PROLIFIC_PL2302 0x0001 /* PL2302 Host-Host */ +#define USB_PRODUCT_PROLIFIC_RSAQ2 0x04bb /* PL2303 Serial */ +#define USB_PRODUCT_PROLIFIC_PL2303BENQ 0x0609 /* PL2303 Serial */ +#define USB_PRODUCT_PROLIFIC_PL2303 0x2303 /* PL2303 Serial */ +#define USB_PRODUCT_PROLIFIC_PL2305 0x2305 /* Parallel printer */ +#define USB_PRODUCT_PROLIFIC_ATAPI4 0x2307 /* ATAPI-4 Bridge Controller */ +#define USB_PRODUCT_PROLIFIC_PL2303GC 0x23a3 /* PL2303 Serial */ +#define USB_PRODUCT_PROLIFIC_PL2303GB 0x23b3 /* PL2303 Serial */ +#define USB_PRODUCT_PROLIFIC_PL2303GT 0x23c3 /* PL2303 Serial */ +#define USB_PRODUCT_PROLIFIC_PL2303GL 0x23d3 /* PL2303 Serial */ +#define USB_PRODUCT_PROLIFIC_PL2303GE 0x23e3 /* PL2303 Serial */ +#define USB_PRODUCT_PROLIFIC_PL2303GS 0x23f3 /* PL2303 Serial */ +#define USB_PRODUCT_PROLIFIC_PL2501 0x2501 /* PL2501 Host-Host */ +#define USB_PRODUCT_PROLIFIC_PL2303X 0xaaa0 /* PL2303 Serial */ +#define USB_PRODUCT_PROLIFIC_PL2303X2 0xaaa2 /* PL2303 Serial */ + +/* Prolific(2) products */ +#define USB_PRODUCT_PROLIFIC2_PL2303 0x2303 /* PL2303 Serial */ + +/* Putercom products */ +#define USB_PRODUCT_PUTERCOM_UPA100 0x047e /* USB-1284 BRIDGE */ + +/* Qcom products */ +#define USB_PRODUCT_QCOM_RT2573 0x6196 /* RT2573 */ +#define USB_PRODUCT_QCOM_RT2573_2 0x6229 /* RT2573 */ +#define USB_PRODUCT_QCOM_RT2573_3 0x6238 /* RT2573 */ +#define USB_PRODUCT_QCOM_RT2870 0x6259 /* RT2870 */ + +/* QNAP products */ +#define USB_PRODUCT_QNAP_UC5G1T 0x0015 /* QNA-UC5G1T */ + +/* Qtronix products */ +#define USB_PRODUCT_QTRONIX_980N 0x2011 /* Scorpion-980N */ + +/* Qualcomm products */ +#define USB_PRODUCT_QUALCOMM_MSM_DRIVER 0x1000 /* MSM driver */ +#define USB_PRODUCT_QUALCOMM_MSM_MODEM 0x3196 /* CDMA MSM modem */ +#define USB_PRODUCT_QUALCOMM_MSM_HSDPA2 0x6000 /* HSDPA MSM */ +#define USB_PRODUCT_QUALCOMM_MSM_HSDPA 0x6613 /* HSDPA MSM */ +#define USB_PRODUCT_QUALCOMM_MSM_HSDPA3 0x9000 /* HSDPA MSM */ +#define USB_PRODUCT_QUALCOMM_MSM_DRIVER2 0xf000 /* MSM driver */ + +/* Qualcomm(2) products */ +#define USB_PRODUCT_QUALCOMM2_MSM_PHONE 0x6000 /* CDMA MSM phone */ + +/* Quanta products */ +#define USB_PRODUCT_QUANTA_RT3070 0x0304 /* RT3070 */ +#define USB_PRODUCT_QUANTA2_UMASS 0x1000 /* Quanta USB MSM (umass mode) */ +#define USB_PRODUCT_QUANTA2_Q101 0xea02 /* Quanta Q101 HSDPA USB modem */ + +/* Quectel products */ +#define USB_PRODUCT_QUECTEL_EC21 0x0121 /* EC21 */ +#define USB_PRODUCT_QUECTEL_EC25 0x0125 /* EC20/EC25 */ +#define USB_PRODUCT_QUECTEL_EG91 0x0191 /* EG91 */ +#define USB_PRODUCT_QUECTEL_EG95 0x0195 /* EG95 */ +#define USB_PRODUCT_QUECTEL_BG96 0x0296 /* BG96 */ +#define USB_PRODUCT_QUECTEL_EG06 0x0306 /* EG06/EP06/EM06 */ +#define USB_PRODUCT_QUECTEL_AG15 0x0415 /* AG15 */ +#define USB_PRODUCT_QUECTEL_AG35 0x0435 /* AG35 */ +#define USB_PRODUCT_QUECTEL_AG520R 0x0452 /* AG520R */ +#define USB_PRODUCT_QUECTEL_AG525R 0x0455 /* AG550R */ +#define USB_PRODUCT_QUECTEL_EG12 0x0512 /* EG12/EM12/EG18 */ +#define USB_PRODUCT_QUECTEL_EG20 0x0620 /* EG20 */ +#define USB_PRODUCT_QUECTEL_BG95 0x0700 /* BG95/BG77/BG600L-M3/BC69 */ +#define USB_PRODUCT_QUECTEL_RG5XXQ 0x0800 /* RG500Q/RM500Q/RG510Q/RM510Q */ + +/* Quickshot products */ +#define USB_PRODUCT_QUICKSHOT_STRIKEPAD 0x6238 /* USB StrikePad */ + +/* Radio Shack products */ +#define USB_PRODUCT_RADIOSHACK_PL2303 0x4026 /* PL2303 Serial */ + +/* Rainbow Technologies products */ +#define USB_PRODUCT_RAINBOW_IKEY2000 0x1200 /* i-Key 2000 */ + +/* Ralink Technology products */ +#define USB_PRODUCT_RALINK_RT2570 0x1706 /* RT2570 */ +#define USB_PRODUCT_RALINK_RT2070 0x2070 /* RT2070 */ +#define USB_PRODUCT_RALINK_RT2570_2 0x2570 /* RT2570 */ +#define USB_PRODUCT_RALINK_RT2573 0x2573 /* RT2573 */ +#define USB_PRODUCT_RALINK_RT2671 0x2671 /* RT2671 */ +#define USB_PRODUCT_RALINK_RT2770 0x2770 /* RT2770 */ +#define USB_PRODUCT_RALINK_RT2870 0x2870 /* RT2870 */ +#define USB_PRODUCT_RALINK_RT3070 0x3070 /* RT3070 */ +#define USB_PRODUCT_RALINK_RT3071 0x3071 /* RT3071 */ +#define USB_PRODUCT_RALINK_RT3072 0x3072 /* RT3072 */ +#define USB_PRODUCT_RALINK_RT3370 0x3370 /* RT3370 */ +#define USB_PRODUCT_RALINK_RT3572 0x3572 /* RT3572 */ +#define USB_PRODUCT_RALINK_RT3573 0x3573 /* RT3573 */ +#define USB_PRODUCT_RALINK_RT5370 0x5370 /* RT5370 */ +#define USB_PRODUCT_RALINK_RT5372 0x5372 /* RT5372 */ +#define USB_PRODUCT_RALINK_RT5572 0x5572 /* RT5572 */ +#define USB_PRODUCT_RALINK_MT7601 0x7601 /* MT7601 */ +#define USB_PRODUCT_RALINK_MT7601_2 0x760a /* MT7601 */ +#define USB_PRODUCT_RALINK_MT7601_3 0x760b /* MT7601 */ +#define USB_PRODUCT_RALINK_MT7601_4 0x760c /* MT7601 */ +#define USB_PRODUCT_RALINK_MT7601_5 0x760d /* MT7601 */ +#define USB_PRODUCT_RALINK_RT8070 0x8070 /* RT8070 */ +#define USB_PRODUCT_RALINK_RT2570_3 0x9020 /* RT2570 */ +#define USB_PRODUCT_RALINK_RT2573_2 0x9021 /* RT2573 */ + +/* RATOC Systems products */ +#define USB_PRODUCT_RATOC_REXUSB60 0xb000 /* USB serial REX-USB60 */ +#define USB_PRODUCT_RATOC_REXUSB60F 0xb020 /* REX-USB60F */ + +/* Realtek products */ +#define USB_PRODUCT_REALTEK_RTL8188ETV 0x0179 /* RTL8188ETV */ +#define USB_PRODUCT_REALTEK_RTL8188CTV 0x018a /* RTL8188CTV */ +#define USB_PRODUCT_REALTEK_RTL8188RU_2 0x317f /* RTL8188RU */ +#define USB_PRODUCT_REALTEK_RTL8188CU_4 0x5088 /* RTL8188CU */ +#define USB_PRODUCT_REALTEK_RTL8152B 0x8050 /* RTL8152B */ +#define USB_PRODUCT_REALTEK_RTL8150 0x8150 /* RTL8150 */ +#define USB_PRODUCT_REALTEK_RTL8151 0x8151 /* RTL8151 PNA */ +#define USB_PRODUCT_REALTEK_RTL8152 0x8152 /* RTL8152 */ +#define USB_PRODUCT_REALTEK_RTL8153 0x8153 /* RTL8153 */ +#define USB_PRODUCT_REALTEK_RTL8156 0x8156 /* RTL8156 */ +#define USB_PRODUCT_REALTEK_RTL8188CE_0 0x8170 /* RTL8188CE */ +#define USB_PRODUCT_REALTEK_RTL8171 0x8171 /* RTL8171 */ +#define USB_PRODUCT_REALTEK_RTL8172 0x8172 /* RTL8172 */ +#define USB_PRODUCT_REALTEK_RTL8173 0x8173 /* RTL8173 */ +#define USB_PRODUCT_REALTEK_RTL8174 0x8174 /* RTL8174 */ +#define USB_PRODUCT_REALTEK_RTL8188CU_0 0x8176 /* RTL8188CU */ +#define USB_PRODUCT_REALTEK_RTL8191CU 0x8177 /* RTL8191CU */ +#define USB_PRODUCT_REALTEK_RTL8192CU 0x8178 /* RTL8192CU */ +#define USB_PRODUCT_REALTEK_RTL8188EU 0x8179 /* RTL8188EU */ +#define USB_PRODUCT_REALTEK_RTL8188CU_1 0x817a /* RTL8188CU */ +#define USB_PRODUCT_REALTEK_RTL8188CU_2 0x817b /* RTL8188CU */ +#define USB_PRODUCT_REALTEK_RTL8192CE 0x817c /* RTL8192CE */ +#define USB_PRODUCT_REALTEK_RTL8188RU 0x817d /* RTL8188RU */ +#define USB_PRODUCT_REALTEK_RTL8188CE_1 0x817e /* RTL8188CE */ +#define USB_PRODUCT_REALTEK_RTL8188RU_3 0x817f /* RTL8188RU */ +#define USB_PRODUCT_REALTEK_RTL8192CE_VAU 0x8186 /* RTL8192CE */ +#define USB_PRODUCT_REALTEK_RTL8187 0x8187 /* RTL8187 */ +#define USB_PRODUCT_REALTEK_RTL8187B_0 0x8189 /* RTL8187B */ +#define USB_PRODUCT_REALTEK_RTL8188CUS 0x818a /* RTL8188CUS */ +#define USB_PRODUCT_REALTEK_RTL8192EU 0x818b /* RTL8192EU */ +#define USB_PRODUCT_REALTEK_RTL8188CU_3 0x8191 /* RTL8188CU */ +#define USB_PRODUCT_REALTEK_RTL8192U 0x8192 /* RTL8192U */ +#define USB_PRODUCT_REALTEK_RTL8187B_1 0x8197 /* RTL8187B */ +#define USB_PRODUCT_REALTEK_RTL8187B_2 0x8198 /* RTL8187B */ +#define USB_PRODUCT_REALTEK_RTL8188CU_5 0x819a /* RTL8188CU */ +#define USB_PRODUCT_REALTEK_RTL8712 0x8712 /* RTL8712 */ +#define USB_PRODUCT_REALTEK_RTL8713 0x8713 /* RTL8713 */ +#define USB_PRODUCT_REALTEK_RTL8188CU_COMBO 0x8754 /* RTL8188CU */ +#define USB_PRODUCT_REALTEK_RTL8723BU 0xb720 /* RTL8723BU */ +#define USB_PRODUCT_REALTEK_RTL8192SU 0xc512 /* RTL8192SU */ +#define USB_PRODUCT_REALTEK_RTL8188FTV 0xf179 /* RTL8188FTV */ + +/* Renesas products */ +#define USB_PRODUCT_RENESAS_RX610 0x0053 /* RX610 RX-Stick */ + +/* Ricoh products */ +#define USB_PRODUCT_RICOH_VGPVCC2 0x1830 /* VGP-VCC2 Camera */ +#define USB_PRODUCT_RICOH_VGPVCC3 0x1832 /* VGP-VCC3 Camera */ +#define USB_PRODUCT_RICOH_VGPVCC2_2 0x1833 /* VGP-VCC2 Camera */ +#define USB_PRODUCT_RICOH_VGPVCC2_3 0x1834 /* VGP-VCC2 Camera */ +#define USB_PRODUCT_RICOH_VGPVCC5 0x1835 /* VGP-VCC5 Camera */ +#define USB_PRODUCT_RICOH_VGPVCC4 0x1836 /* VGP-VCC4 Camera */ +#define USB_PRODUCT_RICOH_VGPVCC4_2 0x1837 /* VGP-VCC4 Camera */ +#define USB_PRODUCT_RICOH_VGPVCC6 0x1839 /* VGP-VCC6 Camera */ +#define USB_PRODUCT_RICOH_VGPVCC7 0x183a /* VGP-VCC7 Camera */ +#define USB_PRODUCT_RICOH_VGPVCC8 0x183b /* VGP-VCC8 Camera */ +#define USB_PRODUCT_RICOH_VGPVCC9 0x183e /* VGP-VCC9 Camera */ +#define USB_PRODUCT_RICOH_VPGVCCX 0x18b2 /* VGP-VCCX Camera */ + +/* Research In Motion products */ +#define USB_PRODUCT_RIM_BLACKBERRY 0x0001 /* BlackBerry */ +#define USB_PRODUCT_RIM_PEARL_DUAL 0x0004 /* RIM Mass Storage Device */ +#define USB_PRODUCT_RIM_PEARL 0x0006 /* BlackBerry pearl */ + +/* Rockfire products */ +#define USB_PRODUCT_ROCKFIRE_GAMEPAD 0x2033 /* Gamepad 203USB */ + +/* Roland products */ +#define USB_PRODUCT_ROLAND_UA100 0x0000 /* UA-100 Audio I/F */ +#define USB_PRODUCT_ROLAND_UM4 0x0002 /* UM-4 MIDI I/F */ +#define USB_PRODUCT_ROLAND_SC8850 0x0003 /* SC-8850 MIDI Synth */ +#define USB_PRODUCT_ROLAND_U8 0x0004 /* U-8 Audio I/F */ +#define USB_PRODUCT_ROLAND_UM2 0x0005 /* UM-2 MIDI I/F */ +#define USB_PRODUCT_ROLAND_SC8820 0x0007 /* SC-8820 MIDI Synth */ +#define USB_PRODUCT_ROLAND_PC300 0x0008 /* PC-300 MIDI Keyboard */ +#define USB_PRODUCT_ROLAND_UM1 0x0009 /* UM-1 MIDI I/F */ +#define USB_PRODUCT_ROLAND_SK500 0x000b /* SK-500 MIDI Keyboard */ +#define USB_PRODUCT_ROLAND_SCD70 0x000c /* SC-D70 MIDI Synth */ +#define USB_PRODUCT_ROLAND_UM880N 0x0014 /* UM-880 MIDI I/F */ +#define USB_PRODUCT_ROLAND_SD90 0x0016 /* SD-90 MIDI Synth */ +#define USB_PRODUCT_ROLAND_UM550 0x0023 /* UM-550 MIDI I/F */ +#define USB_PRODUCT_ROLAND_SD20 0x0027 /* SD-20 MIDI Synth */ +#define USB_PRODUCT_ROLAND_SD80 0x0029 /* SD-80 MIDI Synth */ +#define USB_PRODUCT_ROLAND_UA700 0x002b /* UA-700 Audio I/F */ +#define USB_PRODUCT_ROLAND_UMONE 0x012a /* UM-ONE MIDI I/F */ + +/* RT Systems */ +#define USB_PRODUCT_RTSYSTEMS_CT57B 0x9e52 /* CT57B Radio Cable */ + +/* SACOM products */ +#define USB_PRODUCT_SACOM_USB485BL 0x800d /* USB-485-BL */ + +/* Sagem products */ +#define USB_PRODUCT_SAGEM_SERIAL 0x0027 /* Serial */ +#define USB_PRODUCT_SAGEM_XG760A 0x004a /* XG-760A */ +#define USB_PRODUCT_SAGEM_XG76NA 0x0062 /* XG-76NA */ + +/* Saitek products */ +#define USB_PRODUCT_SAITEK_CYBORG_3D_GOLD 0x0006 /* Cyborg 3D Gold Joystick */ + +/* Samsung products */ +#define USB_PRODUCT_SAMSUNG_WIS09ABGN 0x2018 /* WIS09ABGN Wireless LAN adapter */ +#define USB_PRODUCT_SAMSUNG_SWL2100W 0xa000 /* SWL-2100U */ +#define USB_PRODUCT_SAMSUNG2_RT2870_1 0x2018 /* RT2870 */ +#define USB_PRODUCT_SAMSUNG2_ANDROID2 0x6863 /* Android v2 */ +#define USB_PRODUCT_SAMSUNG2_ANDROID 0x6881 /* Android */ +#define USB_PRODUCT_SAMSUNG2_I330 0x8001 /* I330 */ +#define USB_PRODUCT_SAMSUNG2_AX88179 0xa100 /* AX88179 */ +#define USB_PRODUCT_SAMSUNG2_RTL8153 0xa101 /* RTL8153 */ + +/* SanDisk products */ +#define USB_PRODUCT_SANDISK_SDDR05A 0x0001 /* ImageMate SDDR-05a */ +#define USB_PRODUCT_SANDISK_SDDR31 0x0002 /* ImageMate SDDR-31 */ +#define USB_PRODUCT_SANDISK_SDDR05 0x0005 /* ImageMate SDDR-05 */ +#define USB_PRODUCT_SANDISK_SDDR12 0x0100 /* ImageMate SDDR-12 */ +#define USB_PRODUCT_SANDISK_SDDR09 0x0200 /* ImageMate SDDR-09 */ +#define USB_PRODUCT_SANDISK_SDDR75 0x0810 /* ImageMate SDDR-75 */ + +/* Sanwa Supply products */ +#define USB_PRODUCT_SANWASUPPLY_JYDV9USB 0x9806 /* JY-DV9USB gamepad */ + +/* Sanyo Electric products */ +#define USB_PRODUCT_SANYO_SCP4900 0x0701 /* Sanyo SCP-4900 Phone */ + +/* ScanLogic products */ +#define USB_PRODUCT_SCANLOGIC_SL11R 0x0002 /* SL11R-IDE */ +#define USB_PRODUCT_SCANLOGIC_336CX 0x0300 /* Phantom 336CX - C3 */ + +/* Sealevel products */ +#define USB_PRODUCT_SEALEVEL_2101 0x2101 /* SeaLINK+232 (2101/2105) */ +#define USB_PRODUCT_SEALEVEL_2102 0x2102 /* SeaLINK+485 (2102) */ +#define USB_PRODUCT_SEALEVEL_2103 0x2103 /* SeaLINK+232I (2103) */ +#define USB_PRODUCT_SEALEVEL_2104 0x2104 /* SeaLINK+485I (2104) */ +#define USB_PRODUCT_SEALEVEL_2201_1 0x2211 /* SeaPORT+2/232 (2201) Port 1 */ +#define USB_PRODUCT_SEALEVEL_2202_1 0x2212 /* SeaPORT+2/485 (2202) Port 1 */ +#define USB_PRODUCT_SEALEVEL_2203_1 0x2213 /* SeaPORT+2 (2203) Port 1 */ +#define USB_PRODUCT_SEALEVEL_2201_2 0x2221 /* SeaPORT+2/232 (2201) Port 2 */ +#define USB_PRODUCT_SEALEVEL_2202_2 0x2222 /* SeaPORT+2/485 (2202) Port 2 */ +#define USB_PRODUCT_SEALEVEL_2203_2 0x2223 /* SeaPORT+2 (2203) Port 2 */ +#define USB_PRODUCT_SEALEVEL_2401_1 0x2411 /* SeaPORT+4/232 (2401) Port 1 */ +#define USB_PRODUCT_SEALEVEL_2402_1 0x2412 /* SeaPORT+4/485 (2402) Port 1 */ +#define USB_PRODUCT_SEALEVEL_2403_1 0x2413 /* SeaPORT+4 (2403) Port 1 */ +#define USB_PRODUCT_SEALEVEL_2401_2 0x2421 /* SeaPORT+4/232 (2401) Port 2 */ +#define USB_PRODUCT_SEALEVEL_2402_2 0x2422 /* SeaPORT+4/485 (2402) Port 2 */ +#define USB_PRODUCT_SEALEVEL_2403_2 0x2423 /* SeaPORT+4 (2403) Port 2 */ +#define USB_PRODUCT_SEALEVEL_2401_3 0x2431 /* SeaPORT+4/232 (2401) Port 3 */ +#define USB_PRODUCT_SEALEVEL_2402_3 0x2432 /* SeaPORT+4/485 (2402) Port 3 */ +#define USB_PRODUCT_SEALEVEL_2403_3 0x2433 /* SeaPORT+4 (2403) Port 3 */ +#define USB_PRODUCT_SEALEVEL_2401_4 0x2441 /* SeaPORT+4/232 (2401) Port 4 */ +#define USB_PRODUCT_SEALEVEL_2402_4 0x2442 /* SeaPORT+4/485 (2402) Port 4 */ +#define USB_PRODUCT_SEALEVEL_2403_4 0x2443 /* SeaPORT+4 (2403) Port 4 */ +#define USB_PRODUCT_SEALEVEL_2801_1 0x2811 /* SeaLINK+8/232 (2801) Port 1 */ +#define USB_PRODUCT_SEALEVEL_2802_1 0x2812 /* SeaLINK+8/485 (2802) Port 1 */ +#define USB_PRODUCT_SEALEVEL_2803_1 0x2813 /* SeaLINK+8 (2803) Port 1 */ +#define USB_PRODUCT_SEALEVEL_2801_2 0x2821 /* SeaLINK+8/232 (2801) Port 2 */ +#define USB_PRODUCT_SEALEVEL_2802_2 0x2822 /* SeaLINK+8/485 (2802) Port 2 */ +#define USB_PRODUCT_SEALEVEL_2803_2 0x2823 /* SeaLINK+8 (2803) Port 2 */ +#define USB_PRODUCT_SEALEVEL_2801_3 0x2831 /* SeaLINK+8/232 (2801) Port 3 */ +#define USB_PRODUCT_SEALEVEL_2802_3 0x2832 /* SeaLINK+8/485 (2802) Port 3 */ +#define USB_PRODUCT_SEALEVEL_2803_3 0x2833 /* SeaLINK+8 (2803) Port 3 */ +#define USB_PRODUCT_SEALEVEL_2801_4 0x2841 /* SeaLINK+8/232 (2801) Port 4 */ +#define USB_PRODUCT_SEALEVEL_2802_4 0x2842 /* SeaLINK+8/485 (2802) Port 4 */ +#define USB_PRODUCT_SEALEVEL_2803_4 0x2843 /* SeaLINK+8 (2803) Port 4 */ +#define USB_PRODUCT_SEALEVEL_2801_5 0x2851 /* SeaLINK+8/232 (2801) Port 5 */ +#define USB_PRODUCT_SEALEVEL_2802_5 0x2852 /* SeaLINK+8/485 (2802) Port 5 */ +#define USB_PRODUCT_SEALEVEL_2803_5 0x2853 /* SeaLINK+8 (2803) Port 5 */ +#define USB_PRODUCT_SEALEVEL_2801_6 0x2861 /* SeaLINK+8/232 (2801) Port 6 */ +#define USB_PRODUCT_SEALEVEL_2802_6 0x2862 /* SeaLINK+8/485 (2802) Port 6 */ +#define USB_PRODUCT_SEALEVEL_2803_6 0x2863 /* SeaLINK+8 (2803) Port 6 */ +#define USB_PRODUCT_SEALEVEL_2801_7 0x2871 /* SeaLINK+8/232 (2801) Port 7 */ +#define USB_PRODUCT_SEALEVEL_2802_7 0x2872 /* SeaLINK+8/485 (2802) Port 7 */ +#define USB_PRODUCT_SEALEVEL_2803_7 0x2873 /* SeaLINK+8 (2803) Port 7 */ +#define USB_PRODUCT_SEALEVEL_2801_8 0x2881 /* SeaLINK+8/232 (2801) Port 8 */ +#define USB_PRODUCT_SEALEVEL_2802_8 0x2882 /* SeaLINK+8/485 (2802) Port 8 */ +#define USB_PRODUCT_SEALEVEL_2803_8 0x2883 /* SeaLINK+8 (2803) Port 8 */ +#define USB_PRODUCT_SEALEVEL_2106 0x9020 /* SeaLINK+422 (2106) */ + +/* Schweitzer Engineering Laboratories */ +#define USB_PRODUCT_SEL_C662 0x0001 /* C662 */ + +/* Seluxit products */ +#define USB_PRODUCT_SELUXIT_RF 0x0010 /* RF Dongle */ + +/* Senao products */ +#define USB_PRODUCT_SENAO_RT2870_3 0x0605 /* RT2870 */ +#define USB_PRODUCT_SENAO_RT2870_4 0x0615 /* RT2870 */ +#define USB_PRODUCT_SENAO_NUB8301 0x2000 /* NUB-8301 */ +#define USB_PRODUCT_SENAO_NUB862 0x6100 /* NUB-862 */ +#define USB_PRODUCT_SENAO_RTL8192SU_1 0x9603 /* RTL8192SU */ +#define USB_PRODUCT_SENAO_RTL8192SU_2 0x9605 /* RTL8192SU */ +#define USB_PRODUCT_SENAO_RT2870_1 0x9701 /* RT2870 */ +#define USB_PRODUCT_SENAO_RT2870_2 0x9702 /* RT2870 */ +#define USB_PRODUCT_SENAO_RT3070 0x9703 /* RT3070 */ +#define USB_PRODUCT_SENAO_RT3071 0x9705 /* RT3071 */ +#define USB_PRODUCT_SENAO_RT3072_1 0x9706 /* RT3072 */ +#define USB_PRODUCT_SENAO_RT3072_2 0x9707 /* RT3072 */ +#define USB_PRODUCT_SENAO_RT3072_3 0x9708 /* RT3072 */ +#define USB_PRODUCT_SENAO_RT3072_4 0x9709 /* RT3072 */ +#define USB_PRODUCT_SENAO_RT3072_5 0x9801 /* RT3072 */ + +/* Serverworks */ +#define USB_PRODUCT_SERVERWORKS_HUB 0x0000 /* Root Hub */ + +/* SGI products */ +#define USB_PRODUCT_SGI_SN1_L1_SC 0x1234 /* SN1 L1 System Controller */ + +/* ShanTou products */ +#define USB_PRODUCT_SHANTOU_ST268 0x0268 /* ST268 */ +#define USB_PRODUCT_SHANTOU_DM9620A 0x0269 /* DM9620A */ +#define USB_PRODUCT_SHANTOU_DM9621A 0x1269 /* DM9621A */ +#define USB_PRODUCT_SHANTOU_ZT6688 0x6688 /* ZT6688 */ +#define USB_PRODUCT_SHANTOU_ADM8515 0x8515 /* ADM8515 Ethernet */ +#define USB_PRODUCT_SHANTOU_DM9000E 0x9000 /* DM9000E */ +#define USB_PRODUCT_SHANTOU_DM9601 0x9601 /* DM9601 */ +#define USB_PRODUCT_SHANTOU_DM9620 0x9620 /* DM9620 */ +#define USB_PRODUCT_SHANTOU_DM9621 0x9621 /* DM9621 */ +#define USB_PRODUCT_SHANTOU_DM9622 0x9622 /* DM9622 */ + +/* Shark products */ +#define USB_PRODUCT_SHARK_PA 0x0400 /* Pocket Adapter */ + +/* Sharp products */ +#define USB_PRODUCT_SHARP_SL5500 0x8004 /* SL5500 */ +#define USB_PRODUCT_SHARP_A300 0x8005 /* A300 */ +#define USB_PRODUCT_SHARP_SL5600 0x8006 /* SL5600 */ +#define USB_PRODUCT_SHARP_C700 0x8007 /* C700 */ +#define USB_PRODUCT_SHARP_C750 0x9031 /* C750 */ + +/* Shuttle Technology products */ +#define USB_PRODUCT_SHUTTLE_EUSB 0x0001 /* E-USB Bridge */ +#define USB_PRODUCT_SHUTTLE_EUSCSI 0x0002 /* eUSCSI Bridge */ +#define USB_PRODUCT_SHUTTLE_SDDR09 0x0003 /* ImageMate SDDR09 */ +#define USB_PRODUCT_SHUTTLE_EUSBSMCF 0x0005 /* eUSB SmartMedia / CompactFlash */ +#define USB_PRODUCT_SHUTTLE_ZIOMMC 0x0006 /* eUSB MultiMediaCard */ +#define USB_PRODUCT_SHUTTLE_HIFD 0x0007 /* Sony Hifd */ +#define USB_PRODUCT_SHUTTLE_EUSBATAPI 0x0009 /* eUSB ATA/ATAPI */ +#define USB_PRODUCT_SHUTTLE_CF 0x000a /* eUSB CompactFlash */ +#define USB_PRODUCT_SHUTTLE_EUSCSI_B 0x000b /* eUSCSI Bridge */ +#define USB_PRODUCT_SHUTTLE_EUSCSI_C 0x000c /* eUSCSI Bridge */ +#define USB_PRODUCT_SHUTTLE_CDRW 0x0101 /* CD-RW Device */ +#define USB_PRODUCT_SHUTTLE_SCM 0x1010 /* SCM Micro */ + +/* Siemens products */ +#define USB_PRODUCT_SIEMENS_SPEEDSTREAM 0x1001 /* SpeedStream */ +#define USB_PRODUCT_SIEMENS_SPEEDSTREAM22 0x1022 /* SpeedStream 1022 */ + +/* Siemens(2) products */ +#define USB_PRODUCT_SIEMENS2_WLL013 0x001b /* WLL013 */ +#define USB_PRODUCT_SIEMENS2_ES75 0x0034 /* GSM module MC35 */ + +/* Siemens(3) products */ +#define USB_PRODUCT_SIEMENS3_SX1 0x0001 /* SX1 */ +#define USB_PRODUCT_SIEMENS3_X65 0x0003 /* X65 */ +#define USB_PRODUCT_SIEMENS3_X75 0x0004 /* X75 */ + +/* Siemens(4) products */ +#define USB_PRODUCT_SIEMENS4_RUGGEDCOM 0x01ff /* RUGGEDCOM */ + +/* Sierra Wireless products */ +#define USB_PRODUCT_SIERRA_EM5625 0x0017 /* EM5625 */ +#define USB_PRODUCT_SIERRA_MC5720 0x0018 /* MC5720 */ +#define USB_PRODUCT_SIERRA_AIRCARD_595 0x0019 /* AirCard 595 */ +#define USB_PRODUCT_SIERRA_MC5725 0x0020 /* MC5725 */ +#define USB_PRODUCT_SIERRA_AC597E 0x0021 /* 597E */ +#define USB_PRODUCT_SIERRA_C597 0x0023 /* Compass 597 */ +#define USB_PRODUCT_SIERRA_AIRCARD_580 0x0112 /* Aircard 580 EVDO */ +#define USB_PRODUCT_SIERRA_AC595U 0x0120 /* 595U */ +#define USB_PRODUCT_SIERRA_MC5720_2 0x0218 /* MC5720 */ +#define USB_PRODUCT_SIERRA_MC5725_2 0x0220 /* MC5725 */ +#define USB_PRODUCT_SIERRA_TRUINSTALL 0x0fff /* Aircard Tru Installer */ +#define USB_PRODUCT_SIERRA_MC8755_2 0x6802 /* MC8755 */ +#define USB_PRODUCT_SIERRA_MC8765 0x6803 /* MC8765 */ +#define USB_PRODUCT_SIERRA_MC8755 0x6804 /* MC8755 */ +#define USB_PRODUCT_SIERRA_MC8775 0x6812 /* MC8775 */ +#define USB_PRODUCT_SIERRA_MC8755_3 0x6813 /* MC8755 */ +#define USB_PRODUCT_SIERRA_MC8775_2 0x6815 /* MC8775 */ +#define USB_PRODUCT_SIERRA_AIRCARD_875 0x6820 /* 875 */ +#define USB_PRODUCT_SIERRA_MC8780 0x6832 /* MC8780 */ +#define USB_PRODUCT_SIERRA_MC8781 0x6833 /* MC8781 */ +#define USB_PRODUCT_SIERRA_MC8790 0x683c /* MC8790 */ +#define USB_PRODUCT_SIERRA_AC880 0x6850 /* 880 */ +#define USB_PRODUCT_SIERRA_AC881 0x6851 /* 881 */ +#define USB_PRODUCT_SIERRA_AC880E 0x6852 /* 880E */ +#define USB_PRODUCT_SIERRA_AC881E 0x6853 /* 881E */ +#define USB_PRODUCT_SIERRA_AC880U 0x6855 /* 880U */ +#define USB_PRODUCT_SIERRA_AC881U 0x6856 /* 881U */ +#define USB_PRODUCT_SIERRA_AC885U 0x6880 /* 885U */ +#define USB_PRODUCT_SIERRA_C01SW 0x6890 /* C01SW */ +#define USB_PRODUCT_SIERRA_MC7700 0x68a2 /* MC7700 */ +#define USB_PRODUCT_SIERRA_USB305 0x68a3 /* USB305 */ +#define USB_PRODUCT_SIERRA_MC7304 0x68c0 /* MC7304 */ +#define USB_PRODUCT_SIERRA_MC8355 0x9013 /* MC8355 */ +#define USB_PRODUCT_SIERRA_AIRCARD_340U 0x9051 /* Aircard 340U */ +#define USB_PRODUCT_SIERRA_AIRCARD_770S 0x9053 /* Aircard 770S */ +#define USB_PRODUCT_SIERRA_MC7455 0x9071 /* MC7455 */ +#define USB_PRODUCT_SIERRA_EM7455 0x9079 /* EM7455 */ + +/* Sigmatel products */ +#define USB_PRODUCT_SIGMATEL_IRDA 0x4200 /* IrDA */ +#define USB_PRODUCT_SIGMATEL_DNSSF7X 0x8020 /* Datum Networks SSF-7X Multi Players */ + +/* SIIG products */ +#define USB_PRODUCT_SIIG_DIGIFILMREADER 0x0004 /* DigiFilm-Combo */ +#define USB_PRODUCT_SIIG_MULTICARDREADER 0x0201 /* MULTICARDREADER */ + +/* Silicon Labs products */ +#define USB_PRODUCT_SILABS_VSTABI 0x0f91 /* VStabi Controller */ +#define USB_PRODUCT_SILABS_ARKHAM_DS101_M 0x1101 /* Arkham DS101 Monitor */ +#define USB_PRODUCT_SILABS_ARKHAM_DS101_A 0x1601 /* Arkham DS101 Adapter */ +#define USB_PRODUCT_SILABS_BSM7DUSB 0x800a /* BSM7-D-USB */ +#define USB_PRODUCT_SILABS_POLOLU 0x803b /* Pololu Serial */ +#define USB_PRODUCT_SILABS_SB_PARAMOUNT_ME 0x8043 /* Software Bisque Paramount ME */ +#define USB_PRODUCT_SILABS_CYGNAL_DEBUG 0x8044 /* Cygnal Debug Adapter */ +#define USB_PRODUCT_SILABS_SB_PARAMOUNT_ME2 0x804e /* Software Bisque Paramount ME */ +#define USB_PRODUCT_SILABS_EDG1228 0x8053 /* EDG1228 */ +#define USB_PRODUCT_SILABS_GSM2228 0x8054 /* Enfora GSM2228 */ +#define USB_PRODUCT_SILABS_ARGUSISP 0x8066 /* Argussoft ISP */ +#define USB_PRODUCT_SILABS_IMS_USB_RS422 0x806f /* IMS USB-RS422 */ +#define USB_PRODUCT_SILABS_CRUMB128 0x807a /* Crumb128 */ +#define USB_PRODUCT_SILABS_OPTRIS_MSPRO 0x80c4 /* Optris MSpro LT Thermometer */ +#define USB_PRODUCT_SILABS_DEGREECONT 0x80ca /* Degree Controls */ +#define USB_PRODUCT_SILABS_TRACIENT 0x80dd /* Tracient RFID */ +#define USB_PRODUCT_SILABS_TRAQMATE 0x80ed /* Track Systems Traqmate */ +#define USB_PRODUCT_SILABS_SUUNTO 0x80f6 /* Suunto sports */ +#define USB_PRODUCT_SILABS_ARYGON_MIFARE 0x8115 /* Arygon Mifare RFID reader */ +#define USB_PRODUCT_SILABS_DESKTOPMOBILE 0x813d /* Burnside Desktop mobile */ +#define USB_PRODUCT_SILABS_TAMSMASTER 0x813f /* Tams Master Easy Control */ +#define USB_PRODUCT_SILABS_RIGBLASTER 0x814a /* RIGblaster P&P */ +#define USB_PRODUCT_SILABS_RIGTALK 0x814b /* RIGtalk */ +#define USB_PRODUCT_SILABS_B_G_H3000 0x8156 /* B&G H3000 Data Cable */ +#define USB_PRODUCT_SILABS_IPLINK1220 0x815e /* IP-Link 1220 */ +#define USB_PRODUCT_SILABS_HAMLINKUSB 0x815f /* Timewave HamLinkUSB */ +#define USB_PRODUCT_SILABS_AVIT_USB_TTL 0x818b /* AVIT Research USB-TTL */ +#define USB_PRODUCT_SILABS_MJS_TOSLINK 0x819f /* MJS USB-TOSLINK */ +#define USB_PRODUCT_SILABS_WAVIT 0x81a6 /* ThinkOptics WavIt */ +#define USB_PRODUCT_SILABS_MULTIPLEX_RC 0x81a9 /* Multiplex RC adapter */ +#define USB_PRODUCT_SILABS_MSD_DASHHAWK 0x81ac /* MSD DashHawk */ +#define USB_PRODUCT_SILABS_INSYS_MODEM 0x81ad /* INSYS Modem */ +#define USB_PRODUCT_SILABS_LIPOWSKY_JTAG 0x81c8 /* Lipowsky Baby-JTAG */ +#define USB_PRODUCT_SILABS_LIPOWSKY_LIN 0x81e2 /* Lipowsky Baby-LIN */ +#define USB_PRODUCT_SILABS_AEROCOMM 0x81e7 /* Aerocomm Radio */ +#define USB_PRODUCT_SILABS_ZEPHYR_BIO 0x81e8 /* Zephyr Bioharness */ +#define USB_PRODUCT_SILABS_EMS_C1007 0x81f2 /* EMS C1007 HF RFID reader */ +#define USB_PRODUCT_SILABS_LIPOWSKY_HARP 0x8218 /* Lipowsky HARP-1 */ +#define USB_PRODUCT_SILABS_C2_EDGE_MODEM 0x822b /* Commander 2 EDGE(GSM) Modem */ +#define USB_PRODUCT_SILABS_CYGNAL_GPS 0x826b /* Cygnal Fasttrax GPS */ +#define USB_PRODUCT_SILABS_PLUGDRIVE 0x8281 /* Nanotec Plug & Drive */ +#define USB_PRODUCT_SILABS_TELEGESIS_ETRX2 0x8293 /* Telegesis ETRX2USB */ +#define USB_PRODUCT_SILABS_PROCYON_AVS 0x82f9 /* Procyon AVS */ +#define USB_PRODUCT_SILABS_MC35PU 0x8341 /* MC35pu */ +#define USB_PRODUCT_SILABS_CYGNAL 0x8382 /* Cygnal */ +#define USB_PRODUCT_SILABS_AMBER_AMB2560 0x83a8 /* Amber Wireless AMB2560 */ +#define USB_PRODUCT_SILABS_DEKTEK_DTAPLUS 0x83d8 /* DekTec DTA Plus VHF/UHF Booster */ +#define USB_PRODUCT_SILABS_KYOCERA_GPS 0x8411 /* Kyocera GPS */ +#define USB_PRODUCT_SILABS_IRZ_SG10 0x8418 /* IRZ SG-10 GSM/GPRS Modem */ +#define USB_PRODUCT_SILABS_BEI_VCP 0x846e /* BEI USB Sensor (VCP) */ +#define USB_PRODUCT_SILABS_JUNIPER_BX_CONS 0x8470 /* Juniper BX Console */ +#define USB_PRODUCT_SILABS_BALLUFF_RFID 0x8477 /* Balluff RFID reader */ +#define USB_PRODUCT_SILABS_AC_SERV_IBUS 0x85ea /* AC-Services IBUS */ +#define USB_PRODUCT_SILABS_AC_SERV_CIS 0x85eb /* AC-Services CIS-IBUS */ +#define USB_PRODUCT_SILABS_PREON32 0x85f8 /* Virtenio Preon32 */ +#define USB_PRODUCT_SILABS_AC_SERV_CAN 0x8664 /* AC-Services CAN */ +#define USB_PRODUCT_SILABS_AC_SERV_OBD 0x8665 /* AC-Services OBD */ +#define USB_PRODUCT_SILABS_EM357LR 0x8856 /* CEL EM357 LR */ +#define USB_PRODUCT_SILABS_EM357 0x8857 /* CEL EM357 */ +#define USB_PRODUCT_SILABS_MMB_ZIGBEE 0x88a4 /* MMB Networks ZigBee */ +#define USB_PRODUCT_SILABS_PII_ZIGBEE 0x88a5 /* Planet Innovation Ingeni ZigBee */ +#define USB_PRODUCT_SILABS_KETRA_N1 0x8946 /* Ketra N1 */ +#define USB_PRODUCT_SILABS_CELDEVKIT 0x8977 /* CEL MeshWorks DevKit */ +#define USB_PRODUCT_SILABS_KCF_PRN 0x8998 /* KCF Technologies PRN */ +#define USB_PRODUCT_SILABS_HUBZ 0x8a2a /* HubZ ZigBee/Z-Wave */ +#define USB_PRODUCT_SILABS_CP210X_1 0xea60 /* CP210x Serial */ +#define USB_PRODUCT_SILABS_CP210X_2 0xea61 /* CP210x Serial */ +#define USB_PRODUCT_SILABS_CP210X_3 0xea70 /* CP210x Serial */ +#define USB_PRODUCT_SILABS_INFINITY_MIC 0xea71 /* Infinity GPS-MIC-1 */ +#define USB_PRODUCT_SILABS_CP2110 0xea80 /* CP2110 USB HID Serial */ +#define USB_PRODUCT_SILABS_USBSCOPE50 0xf001 /* USBscope50 */ +#define USB_PRODUCT_SILABS_USBWAVE12 0xf002 /* USBwave12 */ +#define USB_PRODUCT_SILABS_USBPULSE100 0xf003 /* USBpulse100 */ +#define USB_PRODUCT_SILABS_USBCOUNT50 0xf004 /* USBcount50 */ +#define USB_PRODUCT_SILABS2_DCU11CLONE 0xaa26 /* DCU-11 clone */ +#define USB_PRODUCT_SILABS3_GPRS_MODEM 0xea61 /* GPRS Modem */ +#define USB_PRODUCT_SILABS4_100EU_MODEM 0xea6a /* GPRS Modem 100EU */ +#define USB_PRODUCT_SILABS5_EM358X 0x0002 /* EM358x */ + +/* Silicom products */ +#define USB_PRODUCT_SILICOM_U2E 0x0001 /* U2E */ +#define USB_PRODUCT_SILICOM_GPE 0x0002 /* Psion Dacom Gold Port Ethernet */ + +/* Silicon Portals Inc. */ +#define USB_PRODUCT_SILICONPORTALS_YAPPH_NF 0x0200 /* YAP Phone (no firmware) */ +#define USB_PRODUCT_SILICONPORTALS_YAPPHONE 0x0201 /* YAP Phone */ + +/* Simcom products */ +#define USB_PRODUCT_SIMCOM_SIM5320 0x9000 /* SIM5320 modem */ +#define USB_PRODUCT_SIMCOM_SIM7600E 0x9001 /* SIM7600E modem */ +#define USB_PRODUCT_SIMCOM_SIM7600 0x9003 /* SIM7600 LTE */ + +/* Sirius Technologies products */ +#define USB_PRODUCT_SIRIUS_ROADSTER 0x0001 /* NetComm Roadster II 56 */ + +/* Sitecom products */ +#define USB_PRODUCT_SITECOM_LN029 0x182d /* LN029 */ +#define USB_PRODUCT_SITECOM_CN104 0x2068 /* CN104 */ +#define USB_PRODUCT_SITECOM2_WL022 0x182d /* WL-022 */ + +/* Sitecom Europe products */ +#define USB_PRODUCT_SITECOMEU_WL168V1 0x000d /* WL-168 v1 */ +#define USB_PRODUCT_SITECOMEU_RT2870_1 0x0017 /* RT2870 */ +#define USB_PRODUCT_SITECOMEU_LN030 0x0021 /* LN-030 */ +#define USB_PRODUCT_SITECOMEU_WL168V4 0x0028 /* WL-168 v4 */ +#define USB_PRODUCT_SITECOMEU_RT2870_2 0x002b /* RT2870 */ +#define USB_PRODUCT_SITECOMEU_RT2870_3 0x002c /* RT2870 */ +#define USB_PRODUCT_SITECOMEU_WL302 0x002d /* WL-302 */ +#define USB_PRODUCT_SITECOMEU_WL603 0x0036 /* WL-603 */ +#define USB_PRODUCT_SITECOMEU_WL315 0x0039 /* WL-315 */ +#define USB_PRODUCT_SITECOMEU_WL321 0x003b /* WL-321 */ +#define USB_PRODUCT_SITECOMEU_RT3070_3 0x003c /* RT3070 */ +#define USB_PRODUCT_SITECOMEU_WL324 0x003d /* WL-324 */ +#define USB_PRODUCT_SITECOMEU_WL343 0x003e /* WL-343 */ +#define USB_PRODUCT_SITECOMEU_WL608 0x003f /* WL-608 */ +#define USB_PRODUCT_SITECOMEU_WL344 0x0040 /* WL-344 */ +#define USB_PRODUCT_SITECOMEU_WL329 0x0041 /* WL-329 */ +#define USB_PRODUCT_SITECOMEU_WL345 0x0042 /* WL-345 */ +#define USB_PRODUCT_SITECOMEU_WL353 0x0045 /* WL-353 */ +#define USB_PRODUCT_SITECOMEU_RT3072_3 0x0047 /* RT3072 */ +#define USB_PRODUCT_SITECOMEU_RT3072_4 0x0048 /* RT3072 */ +#define USB_PRODUCT_SITECOMEU_WL349V1 0x004b /* WL-349 v1 */ +#define USB_PRODUCT_SITECOMEU_RT3072_6 0x004d /* RT3072 */ +#define USB_PRODUCT_SITECOMEU_WL349V4 0x0050 /* WL-349 v4 */ +#define USB_PRODUCT_SITECOMEU_RT3070_1 0x0051 /* RT3070 */ +#define USB_PRODUCT_SITECOMEU_RTL8188CU 0x0052 /* RTL8188CU */ +#define USB_PRODUCT_SITECOMEU_RTL8188CU_2 0x005c /* RTL8188CU */ +#define USB_PRODUCT_SITECOMEU_RT3072_5 0x005f /* RT3072 */ +#define USB_PRODUCT_SITECOMEU_WLA4000 0x0060 /* WLA-4000 */ +#define USB_PRODUCT_SITECOMEU_RTL8192CU 0x0061 /* RTL8192CU */ +#define USB_PRODUCT_SITECOMEU_WLA5000 0x0062 /* WLA-5000 */ +#define USB_PRODUCT_SITECOMEU_RTL8192CU_2 0x0070 /* RTL8192CU */ +#define USB_PRODUCT_SITECOMEU_LN032 0x0072 /* LN-032 */ +#define USB_PRODUCT_SITECOMEU_WLA2100V2 0x0077 /* WLA-2100 v2 */ +#define USB_PRODUCT_SITECOMEU_LN028 0x061c /* LN-028 */ +#define USB_PRODUCT_SITECOMEU_WL113 0x9071 /* WL-113 */ +#define USB_PRODUCT_SITECOMEU_ZD1211B 0x9075 /* ZD1211B */ +#define USB_PRODUCT_SITECOMEU_WL172 0x90ac /* WL-172 */ +#define USB_PRODUCT_SITECOMEU_WL113R2 0x9712 /* WL-113 rev 2 */ + +/* Smart Technologies products */ +#define USB_PRODUCT_SMART_PL2303 0x2303 /* Serial */ + +/* SmartBridges products */ +#define USB_PRODUCT_SMARTBRIDGES_SMARTLINK 0x0001 /* SmartLink Ethernet */ +#define USB_PRODUCT_SMARTBRIDGES_SMARTNIC 0x0003 /* smartNIC 2 PnP */ + +/* SMC products */ +#define USB_PRODUCT_SMC_2102USB 0x0100 /* 10Mbps Ethernet */ +#define USB_PRODUCT_SMC_2202USB 0x0200 /* 10/100 Ethernet */ +#define USB_PRODUCT_SMC_2206USB 0x0201 /* EZ Connect Ethernet */ +#define USB_PRODUCT_SMC_2862WG 0xee13 /* EZ Connect 54Mbps */ +#define USB_PRODUCT_SMC2_2020HUB 0x2020 /* Hub */ +#define USB_PRODUCT_SMC2_2504HUB 0x2504 /* Hub */ +#define USB_PRODUCT_SMC2_2513HUB 0x2513 /* Hub */ +#define USB_PRODUCT_SMC2_LAN7500 0x7500 /* LAN7500 */ +#define USB_PRODUCT_SMC2_LAN7505 0x7505 /* LAN7505 */ +#define USB_PRODUCT_SMC2_LAN7800 0x7800 /* LAN7800 */ +#define USB_PRODUCT_SMC2_LAN7801 0x7801 /* LAN7801 */ +#define USB_PRODUCT_SMC2_LAN7850 0x7850 /* LAN7850 */ +#define USB_PRODUCT_SMC2_SMSC9500 0x9500 /* SMSC9500 */ +#define USB_PRODUCT_SMC2_SMSC9505 0x9505 /* SMSC9505 */ +#define USB_PRODUCT_SMC2_LAN9530 0x9530 /* LAN9530 */ +#define USB_PRODUCT_SMC2_LAN9730 0x9730 /* LAN9730 */ +#define USB_PRODUCT_SMC2_SMSC9500_SAL10 0x9900 /* SMSC9500 */ +#define USB_PRODUCT_SMC2_SMSC9505_SAL10 0x9901 /* SMSC9505 */ +#define USB_PRODUCT_SMC2_SMSC9500A_SAL10 0x9902 /* SMSC9500A */ +#define USB_PRODUCT_SMC2_SMSC9505A_SAL10 0x9903 /* SMSC9505A */ +#define USB_PRODUCT_SMC2_SMSC9512_14_SAL10 0x9904 /* SMSC9512/14 */ +#define USB_PRODUCT_SMC2_SMSC9500A_HAL 0x9905 /* SMSC9500A */ +#define USB_PRODUCT_SMC2_SMSC9505A_HAL 0x9906 /* SMSC9505A */ +#define USB_PRODUCT_SMC2_SMSC9500_ALT 0x9907 /* SMSC9500 */ +#define USB_PRODUCT_SMC2_SMSC9500A_ALT 0x9908 /* SMSC9500A */ +#define USB_PRODUCT_SMC2_SMSC9512_14_ALT 0x9909 /* SMSC9512 */ +#define USB_PRODUCT_SMC2_SMSC9500A 0x9e00 /* SMSC9500A */ +#define USB_PRODUCT_SMC2_SMSC9505A 0x9e01 /* SMSC9505A */ +#define USB_PRODUCT_SMC2_LAN89530 0x9e08 /* LAN89530 */ +#define USB_PRODUCT_SMC2_SMSC9512_14 0xec00 /* SMSC9512/14 */ +#define USB_PRODUCT_SMC3_2662WV1 0xa001 /* EZ Connect 11Mbps */ +#define USB_PRODUCT_SMC3_2662WV2 0xa002 /* EZ Connect 11Mbps v2 */ + +/* SOHOware products */ +#define USB_PRODUCT_SOHOWARE_NUB100 0x9100 /* NUB100 Ethernet */ +#define USB_PRODUCT_SOHOWARE_NUB110 0x9110 /* NUB110 Ethernet */ + +/* SOLID YEAR products */ +#define USB_PRODUCT_SOLIDYEAR_KEYBOARD 0x2101 /* Keyboard */ + +/* SONY products */ +#define USB_PRODUCT_SONY_DSC 0x0010 /* DSC Cameras */ +#define USB_PRODUCT_SONY_NWMS7 0x0025 /* Memorystick NW-MS7 */ +#define USB_PRODUCT_SONY_DRIVEV2 0x002b /* Harddrive V2 */ +#define USB_PRODUCT_SONY_MSACUS1 0x002d /* Memorystick MSAC-US1 */ +#define USB_PRODUCT_SONY_HANDYCAM 0x002e /* Handycam */ +#define USB_PRODUCT_SONY_MSC 0x0032 /* MSC Memorystick */ +#define USB_PRODUCT_SONY_CLIE_35 0x0038 /* Clie v3.5 */ +#define USB_PRODUCT_SONY_PS2KEYBOARD 0x005c /* PlayStation2 keyboard */ +#define USB_PRODUCT_SONY_PS2KEYBOARDHUB 0x005d /* PlayStation2 keyboard hub */ +#define USB_PRODUCT_SONY_PS2MOUSE 0x0061 /* PlayStation2 mouse */ +#define USB_PRODUCT_SONY_CLIE_40 0x0066 /* Clie v4.0 */ +#define USB_PRODUCT_SONY_CLIE_40_MS 0x006d /* Clie v4.0 Memory Stick */ +#define USB_PRODUCT_SONY_CLIE_S360 0x0095 /* Clie s360 */ +#define USB_PRODUCT_SONY_CLIE_41_MS 0x0099 /* Clie v4.1 Memory Stick */ +#define USB_PRODUCT_SONY_CLIE_41 0x009a /* Clie v4.1 */ +#define USB_PRODUCT_SONY_CLIE_NX60 0x00da /* Clie nx60 */ +#define USB_PRODUCT_SONY_CLIE_TJ25 0x0169 /* Clie tj25 */ +#define USB_PRODUCT_SONY_IFU_WLM2 0x0257 /* IFU-WLM2 */ +#define USB_PRODUCT_SONY_CXD9192 0x0279 /* 1seg TV tuner */ + +/* SOURCENEXT products */ +#define USB_PRODUCT_SOURCENEXT_KEIKAI8_CHG 0x012e /* KeikaiDenwa 8 with charger */ +#define USB_PRODUCT_SOURCENEXT_KEIKAI8 0x039f /* KeikaiDenwa 8 */ + +/* SparkLAN products */ +#define USB_PRODUCT_SPARKLAN_RT2573 0x0004 /* RT2573 */ +#define USB_PRODUCT_SPARKLAN_RT2870_1 0x0006 /* RT2870 */ +#define USB_PRODUCT_SPARKLAN_RT3070 0x0010 /* RT3070 */ +#define USB_PRODUCT_SPARKLAN_RT2870_2 0x0012 /* RT2870 */ + +/* Speed Dragon Multimedia products */ +#define USB_PRODUCT_SPEEDDRAGON_MS3303H 0x110b /* MS3303H Serial */ + +/* Sphairon Access Systems GmbH products */ +#define USB_PRODUCT_SPHAIRON_UB801R 0x0110 /* UB801R */ +#define USB_PRODUCT_SPHAIRON_RTL8187 0x0150 /* RTL8187 */ + +/* StarTech.com products */ +#define USB_PRODUCT_STARTECH_ICUSB232X 0x3410 /* ICUSB2321X/2X/4X */ + +/* STMicroelectronics products */ +#define USB_PRODUCT_STMICRO_BIOMETRIC_COPR 0x2016 /* Biometric Coprocessor */ +#define USB_PRODUCT_STMICRO_COMMUNICATOR 0x7554 /* Communicator */ + +/* Stollmann products */ +#define USB_PRODUCT_STOLLMANN_ISDN_TA_USBA 0x4001 /* ISDN TA+USBA */ + +/* Strawberry Linux products */ +#define USB_PRODUCT_STRAWBERRYLINUX_USBRH 0x1001 /* USBRH sensor */ + +/* STSN products */ +#define USB_PRODUCT_STSN_STSN0001 0x0001 /* Internet Access Device */ + +/* Sun Communications products */ +#define USB_PRODUCT_SUNCOMM_MB_ADAPTOR 0x0003 /* Mobile Adaptor */ + +/* SUN Corporation products */ +#define USB_PRODUCT_SUNTAC_DS96L 0x0003 /* U-Cable type D2 */ +#define USB_PRODUCT_SUNTAC_PS64P1 0x0005 /* U-Cable type P1 */ +#define USB_PRODUCT_SUNTAC_VS10U 0x0009 /* Slipper U */ +#define USB_PRODUCT_SUNTAC_IS96U 0x000a /* Ir-Trinity */ +#define USB_PRODUCT_SUNTAC_AS64LX 0x000b /* U-Cable type A3 */ +#define USB_PRODUCT_SUNTAC_AS144L4 0x0011 /* U-Cable type A4 */ + +/* SuperTop products */ +#define USB_PRODUCT_SUPERTOP_IDEBRIDGE 0x6600 /* SuperTop IDE Bridge */ + +/* Surecom Technology products */ +#define USB_PRODUCT_SURECOM_EP9001G2A 0x11f2 /* EP-9001-G rev 2A */ +#define USB_PRODUCT_SURECOM_RT2570 0x11f3 /* RT2570 */ +#define USB_PRODUCT_SURECOM_RT2573 0x31f3 /* RT2573 */ + +/* Susteen, Inc. products */ +#define USB_PRODUCT_SUSTEEN_DCU11 0x0528 /* Ericsson DCU-10/11 */ + +/* Sweex products */ +#define USB_PRODUCT_SWEEX_ZD1211 0x1809 /* ZD1211 */ +#define USB_PRODUCT_SWEEX2_LW153 0x0153 /* LW153 */ +#define USB_PRODUCT_SWEEX2_LW154 0x0154 /* LW154 */ +#define USB_PRODUCT_SWEEX2_LW303 0x0302 /* LW303 */ +#define USB_PRODUCT_SWEEX2_LW313 0x0313 /* LW313 */ + +/* Synaptics products */ +#define USB_PRODUCT_SYNAPTICS_FPRINT 0x00bd /* Fingerprint Reader */ +#define USB_PRODUCT_SYNAPTICS_FPRINT_2 0x00c2 /* Fingerprint Reader */ + +/* Syntech Information products */ +#define USB_PRODUCT_SYNTECH_SERIAL 0x0001 /* Serial */ +#define USB_PRODUCT_SYNTECH_CIPHERLAB100 0x1000 /* CipherLab Barcode Scanner */ + +/* System TALKS, Inc. */ +#define USB_PRODUCT_SYSTEMTALKS_SGCX2UL 0x1920 /* SGC-X2UL */ + +/* Tangtop products */ +#define USB_PRODUCT_TANGTOP_USBPS2 0x0001 /* USBPS2 */ + +/* Tapwave products */ +#define USB_PRODUCT_TAPWAVE_ZODIAC 0x0100 /* Zodiac */ + +/* Taugagreining products */ +#define USB_PRODUCT_TAUGA_CAMERAMATE 0x0005 /* CameraMate (DPCM_USB) */ + +/* TCT Mobile products */ +#define USB_PRODUCT_TCTMOBILE_UMSM 0x0000 /* Modem mode */ +#define USB_PRODUCT_TCTMOBILE_UMSM_2 0x0017 /* Modem mode */ +#define USB_PRODUCT_TCTMOBILE_UMSM_3 0x011e /* Modem mode */ +#define USB_PRODUCT_TCTMOBILE_UMASS 0xf000 /* Storage mode */ +#define USB_PRODUCT_TCTMOBILE_UMASS_2 0xf017 /* Storage mode */ + +/* TDK products */ +#define USB_PRODUCT_TDK_UPA9664 0x0115 /* USB-PDC Adapter UPA9664 */ +#define USB_PRODUCT_TDK_UCA1464 0x0116 /* USB-cdmaOne Adapter UCA1464 */ +#define USB_PRODUCT_TDK_UHA6400 0x0117 /* USB-PHS Adapter UHA6400 */ +#define USB_PRODUCT_TDK_UPA6400 0x0118 /* USB-PHS Adapter UPA6400 */ +#define USB_PRODUCT_TDK_BLUETOOTH 0x0309 /* Bluetooth */ + +/* TEAC products */ +#define USB_PRODUCT_TEAC_FD05PUB 0x0000 /* FD-05PUB */ + +/* Tekram Technology products */ +#define USB_PRODUCT_TEKRAM_0193 0x1601 /* ALLNET 0193 WLAN */ +#define USB_PRODUCT_TEKRAM_ZYAIR_B200 0x1602 /* ZyXEL ZyAIR B200 WLAN */ +#define USB_PRODUCT_TEKRAM_U300C 0x1612 /* U-300C */ +#define USB_PRODUCT_TEKRAM_QUICKWLAN 0x1630 /* QuickWLAN */ +#define USB_PRODUCT_TEKRAM_ZD1211_1 0x5630 /* ZD1211 */ +#define USB_PRODUCT_TEKRAM_ZD1211_2 0x6630 /* ZD1211 */ + +/* Telex Communications products */ +#define USB_PRODUCT_TELEX_MIC1 0x0001 /* Microphone */ + +/* Tenda */ +#define USB_PRODUCT_TENDA_TWL541U 0x1fab /* TWL541U WLAN */ + +/* Ten X Technology, Inc. */ +#define USB_PRODUCT_TENX_MISSILE 0x0202 /* Missile Launcher */ +#define USB_PRODUCT_TENX_TEMPER 0x660c /* TEMPer sensor */ + +/* TerraTec Electronic GmbH */ +#define USB_PRODUCT_TERRATEC_AUREON 0x0077 /* Aureon Dual USB */ + +/* Testo AG products */ +#define USB_PRODUCT_TESTO_175 0x0001 /* 175/177 USB interface */ +#define USB_PRODUCT_TESTO_330 0x0002 /* 330 USB interface */ +#define USB_PRODUCT_TESTO_435 0x0003 /* 435/635/735 USB interface */ +#define USB_PRODUCT_TESTO_845 0x0004 /* 845 USB interface */ +#define USB_PRODUCT_TESTO_SERVICE 0x0005 /* Service adapter */ +#define USB_PRODUCT_TESTO_580 0x0006 /* 580 USB interface */ +#define USB_PRODUCT_TESTO_174 0x0007 /* 174 USB interface */ +#define USB_PRODUCT_TESTO_556 0x0009 /* 556/560 USB interface */ +#define USB_PRODUCT_TESTO_SERIAL_1 0x000a /* USB adapter */ +#define USB_PRODUCT_TESTO_SERIAL_2 0xf001 /* USB to serial converter */ + +/* ThingM products */ +#define USB_PRODUCT_THINGM_BLINK1 0x01ed /* USB notification light */ + +/* Thrustmaster products */ +#define USB_PRODUCT_THRUST_FUSION_PAD 0xa0a3 /* Fusion Digital Gamepad */ + +/* Thurlby Thandar Instruments products */ +#define USB_PRODUCT_THURLBY_QL355P 0x03e8 /* QL355P power supply */ + +/* Texas Instruments products */ +#define USB_PRODUCT_TI_UTUSB41 0x1446 /* UT-USB41 hub */ +#define USB_PRODUCT_TI_TUSB2046 0x2046 /* TUSB2046 hub */ +#define USB_PRODUCT_TI_TUSB3410 0x3410 /* TUSB3410 */ +#define USB_PRODUCT_TI_NEXII 0x5409 /* Nex II Digital */ +#define USB_PRODUCT_TI_MSP430_JTAG 0xf430 /* MSP-FET430UIF JTAG */ +#define USB_PRODUCT_TI_MSP430 0xf432 /* MSP-FET430UIF */ + +/* The Mobility Lab products */ +#define USB_PRODUCT_TML_SERIAL 0x0064 /* Serial */ + +/* Todos Data System products */ +#define USB_PRODUCT_TODOS_ARGOS_MINI 0x0002 /* Argos Mini Smartcard */ + +/* Topre Corporation products */ +#define USB_PRODUCT_TOPRE_HHKB 0x0100 /* HHKB Professional */ + +/* Toradex Inc. */ +#define USB_PRODUCT_TORADEX_RH 0x0001 /* Toradex OAK RH sensor */ +#define USB_PRODUCT_TORADEX_P 0x0002 /* Toradex OAK P sensor */ +#define USB_PRODUCT_TORADEX_LUX 0x0003 /* Toradex OAK LUX sensor */ +#define USB_PRODUCT_TORADEX_TILT 0x0004 /* Toradex OAK Tilt sensor */ +#define USB_PRODUCT_TORADEX_DIST 0x0005 /* Toradex OAK DIST sensor */ +#define USB_PRODUCT_TORADEX_MOVE 0x0006 /* Toradex OAK MOVE sensor */ +#define USB_PRODUCT_TORADEX_4_20 0x0009 /* Toradex OAK 4-20mA sensor */ +#define USB_PRODUCT_TORADEX_G 0x000a /* Toradex OAK G sensor */ +#define USB_PRODUCT_TORADEX_MAGR 0x000b /* Toradex OAK MAGR sensor */ +#define USB_PRODUCT_TORADEX_RELAY 0x000d /* Toradex OAK RELAY */ +#define USB_PRODUCT_TORADEX_10V 0x000e /* Toradex OAK 10V sensor */ +#define USB_PRODUCT_TORADEX_LN 0x000f /* Toradex OAK LN sensor */ +#define USB_PRODUCT_TORADEX_IO 0x0010 /* Toradex OAK IO */ +#define USB_PRODUCT_TORADEX_ORIENT 0x0015 /* Toradex ORIENT Tilt sensor */ + +/* Toshiba Corp products */ +#define USB_PRODUCT_TOSHIBA_RTL8153B 0x0416 /* RTL8153B */ +#define USB_PRODUCT_TOSHIBA_RT3070 0x0a07 /* RT3070 */ +#define USB_PRODUCT_TOSHIBA_HSDPA 0x1302 /* HSDPA */ + +/* TP-Link products */ +#define USB_PRODUCT_TPLINK_RTL8192CU 0x0100 /* RTL8192CU */ +#define USB_PRODUCT_TPLINK_RTL8812AU 0x0101 /* RTL8812AU */ +#define USB_PRODUCT_TPLINK_RTL8192EU 0x0107 /* RTL8192EU */ +#define USB_PRODUCT_TPLINK_RTL8192EU_2 0x0108 /* RTL8192EU */ +#define USB_PRODUCT_TPLINK_RTL8192EU_3 0x0109 /* RTL8192EU */ +#define USB_PRODUCT_TPLINK_RTL8188EUS 0x010c /* RTL8188EUS */ +#define USB_PRODUCT_TPLINK_EU300 0x0601 /* EU300 */ +#define USB_PRODUCT_TPLINK_RTL8152B_1 0x0602 /* RTL8152B */ +#define USB_PRODUCT_TPLINK_RTL8152B_2 0x0603 /* RTL8152B */ +#define USB_PRODUCT_TPLINK_RTL8153 0x0604 /* RTL8153 */ + +/* Trek Technology products */ +#define USB_PRODUCT_TREK_THUMBDRIVE 0x1111 /* ThumbDrive */ +#define USB_PRODUCT_TREK_THUMBDRIVE_8MB 0x9988 /* ThumbDrive 8MB */ + +/* TRENDnet products */ +#define USB_PRODUCT_TRENDNET_RTL8192CU 0x624d /* RTL8192CU */ +#define USB_PRODUCT_TRENDNET_RTL8188CU 0x648b /* RTL8188CU */ +#define USB_PRODUCT_TRENDNET_RTL8156 0xe02b /* RTL8156 */ +#define USB_PRODUCT_TRENDNET_TUCET5G 0xe05a /* TUC-ET5G */ + +/* Tripp-Lite products */ +#define USB_PRODUCT_TRIPPLITE_U209 0x2008 /* U209 Serial */ + +/* Trumpion products */ +#define USB_PRODUCT_TRUMPION_T33521 0x1003 /* USB/MP3 decoder */ +#define USB_PRODUCT_TRUMPION_XXX1100 0x1100 /* XXX 1100 */ + +/* Trust products */ +#define USB_PRODUCT_TRUST_OPTMOUSE 0x0a33 /* Optical Mouse */ +#define USB_PRODUCT_TRUST_MOUSE 0x0a37 /* Mouse */ + +/* Tsunami products */ +#define USB_PRODUCT_TSUNAMI_SM2000 0x1111 /* SM-2000 */ + +/* Technology Testing Lab products */ +#define USB_PRODUCT_TTL_RTL8153 0x104e /* RTL8153 */ + +/* Twinhead products */ +#define USB_PRODUCT_TWINHEAD_RTL8153B 0x1400 /* RTL8153B */ + +/* TwinMOS products */ +#define USB_PRODUCT_TWINMOS_G240 0xa006 /* G240 */ + +/* U-blox AG */ +#define USB_PRODUCT_UBLOX_ANTARIS4 0x01a4 /* ANTARIS4 GPS */ + +/* Ultima products */ +#define USB_PRODUCT_ULTIMA_1200UBPLUS 0x4002 /* 1200 UB Plus */ + +/* UMAX products */ +#define USB_PRODUCT_UMAX_ASTRA1236U 0x0002 /* Astra 1236U */ +#define USB_PRODUCT_UMAX_ASTRA1220U 0x0010 /* Astra 1220U */ +#define USB_PRODUCT_UMAX_ASTRA2000U 0x0030 /* Astra 2000U */ +#define USB_PRODUCT_UMAX_ASTRA3400 0x0060 /* Astra 3400 */ +#define USB_PRODUCT_UMAX_ASTRA2100U 0x0130 /* Astra 2100U */ +#define USB_PRODUCT_UMAX_ASTRA2200U 0x0230 /* Astra 2200U */ + +/* U-MEDIA Communications products */ +#define USB_PRODUCT_UMEDIA_TEW444UBEU 0x3006 /* TEW-444UB EU */ +#define USB_PRODUCT_UMEDIA_TEW444UBEU_NF 0x3007 /* TEW-444UB EU */ +#define USB_PRODUCT_UMEDIA_TEW429UB_A 0x300a /* TEW-429UB_A */ +#define USB_PRODUCT_UMEDIA_TEW429UB 0x300b /* TEW-429UB */ +#define USB_PRODUCT_UMEDIA_TEW429UBC1 0x300d /* TEW-429UB C1 */ +#define USB_PRODUCT_UMEDIA_RT2870_1 0x300e /* RT2870 */ +#define USB_PRODUCT_UMEDIA_TEW645UB 0x3013 /* TEW-645UB */ +#define USB_PRODUCT_UMEDIA_ALL0298V2 0x3204 /* ALL0298 v2 */ +#define USB_PRODUCT_UMEDIA_AR5523_2 0x3205 /* AR5523 */ +#define USB_PRODUCT_UMEDIA_AR5523_2_NF 0x3206 /* AR5523 */ + +/* Universal Access products */ +#define USB_PRODUCT_UNIACCESS_PANACHE 0x0101 /* Panache Surf ISDN */ + +/* Unknown vendor 2 */ +#define USB_PRODUCT_UNKNOWN2_ZD1211B 0x0105 /* ZD1211B */ +#define USB_PRODUCT_UNKNOWN2_NW3100 0x145f /* NW-3100 */ + +/* Unknown vendor 3 */ +#define USB_PRODUCT_UNKNOWN3_ZD1211B 0x1233 /* ZD1211B */ + +/* Unknown vendor 4 */ +#define USB_PRODUCT_UNKNOWN4_DM9601 0x8101 /* DM9601 */ +#define USB_PRODUCT_UNKNOWN4_RD9700 0x9700 /* RD9700 */ + +/* Unknown vendor 5 */ +#define USB_PRODUCT_UNKNOWN5_NF_RIC 0x0001 /* NF RIC */ + +/* Unknown vendor 6 */ +#define USB_PRODUCT_UNKNOWN6_DM9601 0x9601 /* DM9601 */ + +/* USI products */ +#define USB_PRODUCT_USI_MC60 0x10c5 /* MC60 Serial */ + +/* U.S. Robotics products */ +#define USB_PRODUCT_USR_USR1120 0x00eb /* USR1120 WLAN */ +#define USB_PRODUCT_USR_MILLER_A 0x00f1 /* USR9000 SureConnect ADSL */ +#define USB_PRODUCT_USR_MILLER_A_NF 0x00f2 /* USR9000 SureConnect ADSL */ +#define USB_PRODUCT_USR_HEINEKEN_A 0x00f5 /* USR9000 SureConnect ADSL */ +#define USB_PRODUCT_USR_HEINEKEN_A_NF 0x00f6 /* USR9000 SureConnect ADSL */ +#define USB_PRODUCT_USR_HEINEKEN_B 0x00f7 /* USR9000 SureConnect ADSL */ +#define USB_PRODUCT_USR_HEINEKEN_B_NF 0x00f8 /* USR9000 SureConnect ADSL */ +#define USB_PRODUCT_USR_MILLER_B 0x00f9 /* USR9000 SureConnect ADSL */ +#define USB_PRODUCT_USR_MILLER_B_NF 0x00fa /* USR9000 SureConnect ADSL */ +#define USB_PRODUCT_USR_USR5422 0x0118 /* USR5422 WLAN */ +#define USB_PRODUCT_USR_USR5421A 0x011b /* USR5421A WLAN */ +#define USB_PRODUCT_USR_USR5423 0x0121 /* USR5423 WLAN */ + +/* Vaisala Products */ +#define USB_PRODUCT_VAISALA_USBINSTCABLE 0x0200 /* USB instrument cable */ + +/* Validity Sensors products */ +#define USB_PRODUCT_VALIDITY_VFS101 0x0001 /* VFS101 Fingerprint Reader */ +#define USB_PRODUCT_VALIDITY_VFS301 0x0005 /* VFS301 Fingerprint Reader */ +#define USB_PRODUCT_VALIDITY_VFS451 0x0007 /* VFS451 Fingerprint Reader */ +#define USB_PRODUCT_VALIDITY_VFS300 0x0008 /* VFS300 Fingerprint Reader */ +#define USB_PRODUCT_VALIDITY_VFS5011 0x0011 /* VFS5011 Fingerprint Reader */ +#define USB_PRODUCT_VALIDITY_VFS5011_2 0x0017 /* VFS5011 Fingerprint Reader */ +#define USB_PRODUCT_VALIDITY_VFS5011_3 0x0018 /* VFS5011 Fingerprint Reader */ +#define USB_PRODUCT_VALIDITY_VFS5471 0x003c /* VFS471 Fingerprint Reader */ + +/* Velleman products */ +#define USB_PRODUCT_VELLEMAN_K8055 0x5500 /* K8055 USB Experiment interface board */ + +/* Vertex Wireless products */ +#define USB_PRODUCT_VERTEX_VW110L 0x0100 /* VW110L */ + +/* VIA products */ +#define USB_PRODUCT_VIA_AR9271 0x3801 /* AR9271 */ + +/* ViewSonic products */ +#define USB_PRODUCT_VIEWSONIC_G773HUB 0x00fe /* G773 Monitor Hub */ +#define USB_PRODUCT_VIEWSONIC_P815HUB 0x00ff /* P815 Monitor Hub */ +#define USB_PRODUCT_VIEWSONIC_AIRSYNC 0x0f01 /* Airsync */ +#define USB_PRODUCT_VIEWSONIC_G773CTRL 0x4153 /* G773 Monitor Control */ + +/* Vision products */ +#define USB_PRODUCT_VISION_VC6452V002 0x0002 /* CPiA Camera */ + +/* Visioneer products */ +#define USB_PRODUCT_VISIONEER_7600 0x0211 /* OneTouch 7600 */ +#define USB_PRODUCT_VISIONEER_5300 0x0221 /* OneTouch 5300 */ +#define USB_PRODUCT_VISIONEER_3000 0x0224 /* Scanport 3000 */ +#define USB_PRODUCT_VISIONEER_6100 0x0231 /* OneTouch 6100 */ +#define USB_PRODUCT_VISIONEER_6200 0x0311 /* OneTouch 6200 */ +#define USB_PRODUCT_VISIONEER_8100 0x0321 /* OneTouch 8100 */ +#define USB_PRODUCT_VISIONEER_8600 0x0331 /* OneTouch 8600 */ + +/* Vivitar products */ +#define USB_PRODUCT_VIVITAR_DSC350 0x0003 /* DSC350 */ + +/* Van Ooijen Technische Informatica products */ +#define USB_PRODUCT_VOTI_SELETEK_1 0x09b0 /* Lunatico Seletek */ +#define USB_PRODUCT_VOTI_SELETEK_2 0x09b1 /* Lunatico Seletek */ + +/* VTech products */ +#define USB_PRODUCT_VTECH_RT2570 0x3012 /* RT2570 */ +#define USB_PRODUCT_VTECH_ZD1211B 0x3014 /* ZD1211B */ + +/* Wacom products */ +#define USB_PRODUCT_WACOM_CT0405U 0x0000 /* CT-0405-U Tablet */ +#define USB_PRODUCT_WACOM_GRAPHIRE 0x0010 /* Graphire */ +#define USB_PRODUCT_WACOM_GRAPHIRE3_4X5 0x0013 /* Graphire3 4x5 */ +#define USB_PRODUCT_WACOM_GRAPHIRE4_4X5 0x0015 /* Graphire4 Classic A6 */ +#define USB_PRODUCT_WACOM_INTUOSA5 0x0021 /* Intuos A5 */ +#define USB_PRODUCT_WACOM_INTUOS_DRAW 0x033b /* Intuos Draw (CTL-490) */ +#define USB_PRODUCT_WACOM_ONE_S 0x037a /* One S (CTL-472) */ +#define USB_PRODUCT_WACOM_ONE_M 0x037b /* One M (CTL-672) */ +#define USB_PRODUCT_WACOM_INTUOS_PRO_S 0x0392 /* Intuos Pro S */ + +/* WAGO Kontakttechnik products */ +#define USB_PRODUCT_WAGO_SERVICECABLE 0x07a6 /* Service Cable 750-923 */ + +/* WaveSense products */ +#define USB_PRODUCT_WAVESENSE_JAZZ 0xaaaa /* Jazz blood glucose meter */ + +/* WCH/QinHeng Electronics */ +#define USB_PRODUCT_WCH_CH341 0x5523 /* CH341 serial/parallel */ +#define USB_PRODUCT_WCH2_CH341A 0x5523 /* CH341A serial/parallel */ +#define USB_PRODUCT_WCH2_CH340 0x7523 /* CH340 serial/parallel */ +#define USB_PRODUCT_WCH2_TEMPER 0xe025 /* TEMPer sensor */ + +/* WIENER Plein & Baus products */ +#define USB_PRODUCT_WIENERPLEINBAUS_PL512 0x0010 /* PL512 PSU */ +#define USB_PRODUCT_WIENERPLEINBAUS_RCM 0x0011 /* RCM Remote Control */ +#define USB_PRODUCT_WIENERPLEINBAUS_MPOD 0x0012 /* MPOD PSU */ +#define USB_PRODUCT_WIENERPLEINBAUS_CML 0x0015 /* CML Data Logger */ + +/* Wistron NeWeb products */ +#define USB_PRODUCT_WISTRONNEWEB_WNC0600 0x0326 /* WNC-0600USB */ +#define USB_PRODUCT_WISTRONNEWEB_UR045G 0x0427 /* PrismGT USB 2.0 WLAN */ +#define USB_PRODUCT_WISTRONNEWEB_UR055G 0x0711 /* UR055G */ +#define USB_PRODUCT_WISTRONNEWEB_O8494 0x0804 /* ORiNOCO 802.11n */ +#define USB_PRODUCT_WISTRONNEWEB_AR5523_1 0x0826 /* AR5523 */ +#define USB_PRODUCT_WISTRONNEWEB_AR5523_1_NF 0x0827 /* AR5523 */ +#define USB_PRODUCT_WISTRONNEWEB_AR5523_2_NF 0x0829 /* AR5523 */ +#define USB_PRODUCT_WISTRONNEWEB_AR5523_2 0x082a /* AR5523 */ + +/* West Mountain Radio products */ +#define USB_PRODUCT_WMR_RIGBLASTER 0x0003 /* RIGblaster */ + +/* Xiaomi products */ +#define USB_PRODUCT_XIAOMI_RTL8152B 0x0011 /* RTL8152B */ +#define USB_PRODUCT_XIAOMI_MT7601U 0x4106 /* MT7601U */ + +/* XIRING products */ +#define USB_PRODUCT_XIRING_XIMAX 0x0005 /* Ximax CDC */ + +/* Xirlink products */ +#define USB_PRODUCT_XIRLINK_IMAGING 0x800d /* Imaging Device */ +#define USB_PRODUCT_XIRLINK_PCCAM 0x8080 /* IBM PC Camera */ + +/* Xyratex products */ +#define USB_PRODUCT_XYRATEX_PRISM_GT_1 0x2000 /* PrismGT USB 2.0 WLAN */ +#define USB_PRODUCT_XYRATEX_PRISM_GT_2 0x2002 /* PrismGT USB 2.0 WLAN */ + +/* Yamaha products */ +#define USB_PRODUCT_YAMAHA_UX256 0x1000 /* UX256 MIDI I/F */ +#define USB_PRODUCT_YAMAHA_UX96 0x1008 /* UX96 MIDI I/F */ +#define USB_PRODUCT_YAMAHA_UR22 0x1509 /* UR22 */ +#define USB_PRODUCT_YAMAHA_RPU200 0x3104 /* RP-U200 */ +#define USB_PRODUCT_YAMAHA_RTA54I 0x4000 /* NetVolante RTA54i */ +#define USB_PRODUCT_YAMAHA_RTW65B 0x4001 /* NetVolante RTW65b */ +#define USB_PRODUCT_YAMAHA_RTW65I 0x4002 /* NetVolante RTW65i */ +#define USB_PRODUCT_YAMAHA_RTA55I 0x4004 /* NetVolante RTA55i */ + +/* Yano products */ +#define USB_PRODUCT_YANO_U640MO 0x0101 /* U640MO-03 */ + +/* Y.C. Cable products */ +#define USB_PRODUCT_YCCABLE_PL2303 0x0fba /* PL2303 Serial */ + +/* Y-E Data products */ +#define USB_PRODUCT_YEDATA_FLASHBUSTERU 0x0000 /* Flashbuster-U */ + +/* Yubico products */ +#define USB_PRODUCT_YUBICO_YUBIKEY 0x0010 /* Yubikey */ + +/* Z-Com products */ +#define USB_PRODUCT_ZCOM_M4Y750 0x0001 /* M4Y-750 */ +#define USB_PRODUCT_ZCOM_XI725 0x0002 /* XI-725/726 */ +#define USB_PRODUCT_ZCOM_XI735 0x0005 /* XI-735 */ +#define USB_PRODUCT_ZCOM_MD40900 0x0006 /* MD40900 */ +#define USB_PRODUCT_ZCOM_XG703A 0x0008 /* PrismGT USB 2.0 WLAN */ +#define USB_PRODUCT_ZCOM_ZD1211 0x0011 /* ZD1211 */ +#define USB_PRODUCT_ZCOM_AR5523 0x0012 /* AR5523 */ +#define USB_PRODUCT_ZCOM_AR5523_NF 0x0013 /* AR5523 */ +#define USB_PRODUCT_ZCOM_ZD1211B 0x001a /* ZD1211B */ +#define USB_PRODUCT_ZCOM_RT2870_1 0x0022 /* RT2870 */ +#define USB_PRODUCT_ZCOM_UB81 0x0023 /* UB81 */ +#define USB_PRODUCT_ZCOM_RT2870_2 0x0025 /* RT2870 */ +#define USB_PRODUCT_ZCOM_UB82 0x0026 /* UB82 */ + +/* Zinwell products */ +#define USB_PRODUCT_ZINWELL_RT2570 0x0260 /* RT2570 */ +#define USB_PRODUCT_ZINWELL_RT2870_1 0x0280 /* RT2870 */ +#define USB_PRODUCT_ZINWELL_RT2870_2 0x0282 /* RT2870 */ +#define USB_PRODUCT_ZINWELL_RT3072_1 0x0283 /* RT3072 */ +#define USB_PRODUCT_ZINWELL_RT3072_2 0x0284 /* RT3072 */ +#define USB_PRODUCT_ZINWELL_RT3070 0x5257 /* RT3070 */ + +/* Zoom Telephonics, Inc. products */ +#define USB_PRODUCT_ZOOM_2986L 0x9700 /* 2986L Fax Modem */ + +/* ZTE products */ +#define USB_PRODUCT_ZTE_CDMA_MSM 0x0001 /* CDMA Technologies MSM modem */ +#define USB_PRODUCT_ZTE_MF633 0x0016 /* ZTE MF633 USUPA USB modem */ +#define USB_PRODUCT_ZTE_MF637 0x0031 /* ZTE MF637 HSUPA USB modem */ +#define USB_PRODUCT_ZTE_K3565Z 0x0063 /* ZTE K3565-Z USB MSM modem */ +#define USB_PRODUCT_ZTE_UMASS_INSTALLER4 0x0083 /* ZTE USB MSM installer */ +#define USB_PRODUCT_ZTE_MSA110UP 0x0091 /* ONDA MSA110UP USB MSM modem */ +#define USB_PRODUCT_ZTE_UMASS_INSTALLER2 0x0103 /* ZTE USB MSM installer */ +#define USB_PRODUCT_ZTE_MF112 0x0117 /* ZTE MF112 HSUPA USB modem */ +#define USB_PRODUCT_ZTE_HSUSB 0x1364 /* ZTE HSUSB */ +#define USB_PRODUCT_ZTE_UMASS_INSTALLER 0x2000 /* ZTE USB MSM installer */ +#define USB_PRODUCT_ZTE_AC2746 0xfff1 /* AC2746 CDMA USB modem */ +#define USB_PRODUCT_ZTE_UMASS_INSTALLER3 0xfff5 /* ZTE USB CDMA installer */ +#define USB_PRODUCT_ZTE_AC8700 0xfffe /* AC8700 CDMA USB modem */ + +/* ZyDAS Technology products */ +#define USB_PRODUCT_ZYDAS_ZD1201 0x1201 /* ZD1201 */ +#define USB_PRODUCT_ZYDAS_ZD1211 0x1211 /* ZD1211 */ +#define USB_PRODUCT_ZYDAS_ZD1211B 0x1215 /* ZD1211B */ +#define USB_PRODUCT_ZYDAS_ZD1221 0x1221 /* ZD1221 */ +#define USB_PRODUCT_ZYDAS_ALL0298 0xa211 /* ALL0298 */ +#define USB_PRODUCT_ZYDAS_ZD1211B_2 0xb215 /* ZD1211B */ + +/* ZyXEL Communication Co. products */ +#define USB_PRODUCT_ZYXEL_OMNI56K 0x1500 /* Omni 56K Plus */ +#define USB_PRODUCT_ZYXEL_980N 0x2011 /* Scorpion-980N */ +#define USB_PRODUCT_ZYXEL_G220 0x3401 /* G-220 */ +#define USB_PRODUCT_ZYXEL_G220F 0x3402 /* G-220F */ +#define USB_PRODUCT_ZYXEL_G200V2 0x3407 /* G-200 v2 */ +#define USB_PRODUCT_ZYXEL_AG225H 0x3409 /* AG-225H */ +#define USB_PRODUCT_ZYXEL_M202 0x340a /* M-202 */ +#define USB_PRODUCT_ZYXEL_G270S 0x340c /* G-270S */ +#define USB_PRODUCT_ZYXEL_G220V2 0x340f /* G-220 v2 */ +#define USB_PRODUCT_ZYXEL_G202 0x3410 /* G-202 */ +#define USB_PRODUCT_ZYXEL_AG220 0x3412 /* AG-220 */ +#define USB_PRODUCT_ZYXEL_AG225HV2 0x3413 /* AG-225H v2 */ +#define USB_PRODUCT_ZYXEL_RT2573 0x3415 /* RT2573 */ +#define USB_PRODUCT_ZYXEL_RT2870_1 0x3416 /* RT2870 */ +#define USB_PRODUCT_ZYXEL_NWD271N 0x3417 /* NWD-271N */ +#define USB_PRODUCT_ZYXEL_NWD211AN 0x3418 /* NWD-211AN */ +#define USB_PRODUCT_ZYXEL_RT2870_2 0x341a /* RT2870 */ +#define USB_PRODUCT_ZYXEL_NWD2105 0x341e /* NWD2105 */ +#define USB_PRODUCT_ZYXEL_RTL8192CU 0x341f /* RTL8192CU */ +#define USB_PRODUCT_ZYXEL_RT3070 0x343e /* RT3070 */ +#define USB_PRODUCT_ZYXEL_PRESTIGE 0x401a /* Prestige */ diff --git a/sys/dev/athn/headers/openbsd_adapt.h b/sys/dev/athn/headers/openbsd_adapt.h new file mode 100644 --- /dev/null +++ b/sys/dev/athn/headers/openbsd_adapt.h @@ -0,0 +1,162 @@ +/* $OpenBSD: time.h,v 1.63 2022/12/13 17:30:36 cheloha Exp $ */ +/* $NetBSD: time.h,v 1.18 1996/04/23 10:29:33 mycroft Exp $ */ + +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)time.h 8.2 (Berkeley) 7/10/94 + */ + +#ifndef _OPENBSD_ADAPT_H_ +#define _OPENBSD_ADAPT_H_ + +/* + * Set to 1 to 'uncomment' (enable) + * parts of the code that depend on the USB OpenBSD API + */ +#define OpenBSD_IEEE80211_API 0 + +/* + * Code marked by this macro + * needs a OpenBSD equivalent function or complete rework + * Some might not be needed. + * Set to 1 to 'uncomment' (enable) + */ +#define OpenBSD_ONLY 0 + +#include +// map OpenBSD endian conversion macro names to FreeBSD +#define betoh16 be16toh +#define betoh32 be32toh +#define betoh64 be64toh +#define letoh16 le16toh + +// map OpenBSD flag name to FreeBSD +#define IFF_RUNNING IFF_DRV_RUNNING + +// map 3-argument OpenBSD free function to 2-argument FreeBSD one +// if the number of arguments is 2 - do nothing +#define free(addr,type,...) free(addr,type) + +#define IEEE80211_HT_NUM_MCS 77 +#define IEEE80211_DUR_DS_SHSLOT 9 +#define MBUF_LIST_INITIALIZER() { NULL, NULL, 0 } + + +struct mbuf_list { + struct mbuf *ml_head; + struct mbuf *ml_tail; + u_int ml_len; +}; + +enum ieee80211_edca_ac { + EDCA_AC_BK = 1, /* Background */ + EDCA_AC_BE = 0, /* Best Effort */ + EDCA_AC_VI = 2, /* Video */ + EDCA_AC_VO = 3 /* Voice */ +}; + + + +// TODO: try remove these defines, use proper include instead + +#define SIMPLEQ_ENTRY(type) \ +struct { \ + struct type *sqe_next; /* next element */ \ +} + +#define SIMPLEQ_FIRST(head) ((head)->sqh_first) +#define SIMPLEQ_END(head) NULL +#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) +#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) + + +#define SIMPLEQ_HEAD(name, type) \ +struct name { \ + struct type *sqh_first; /* first element */ \ + struct type **sqh_last; /* addr of last next element */ \ +} + +#define SIMPLEQ_REMOVE_HEAD(head, field) do { \ + if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.sqe_next = NULL; \ + *(head)->sqh_last = (elm); \ + (head)->sqh_last = &(elm)->field.sqe_next; \ +} while (0) + +#define SIMPLEQ_INIT(head) do { \ + (head)->sqh_first = NULL; \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + + +static inline uint64_t +SEC_TO_NSEC(uint64_t seconds) +{ + if (seconds > UINT64_MAX / 1000000000ULL) + return UINT64_MAX; + return seconds * 1000000000ULL; +} + +static inline uint64_t +MSEC_TO_NSEC(uint64_t milliseconds) +{ + if (milliseconds > UINT64_MAX / 1000000ULL) + return UINT64_MAX; + return milliseconds * 1000000ULL; +} + +// ifq_oactive is not available in FreeBSD. +// Need to use additional variable to provide this functionality. +extern unsigned int ifq_oactive; + +static inline void +ifq_clr_oactive() +{ + ifq_oactive = 0; +} + +static inline unsigned int +ifq_is_oactive() +{ + return ifq_oactive; +} + +static inline void +ifq_set_oactive() +{ + ifq_oactive = 1; +} + +static __inline intrmask_t splusb(void) { return 0; } + +#endif /* _OPENBSD_ADAPT_H_ */ diff --git a/sys/dev/athn/if_athn_usb.c b/sys/dev/athn/if_athn_usb.c new file mode 100644 --- /dev/null +++ b/sys/dev/athn/if_athn_usb.c @@ -0,0 +1,3622 @@ +/* $OpenBSD: if_athn_usb.c,v 1.65 2022/07/10 21:13:41 bluhm Exp $ */ + +/*- + * Copyright (c) 2011 Damien Bergamini + * Copyright (c) 2018 Stefan Sperling + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * USB front-end for Atheros AR9271 and AR7010 chipsets. + */ + +// #include "bpfilter.h" +#define NBPFILTER 0 // TODO ? +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if NBPFILTER > 0 +#include +#endif +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "athnreg.h" +#include "ar5008reg.h" +#include "athnvar.h" + +#include + +#include +#include +#include +//#include +#include + +#include "openbsd_adapt.h" +#include "if_athn_usb.h" +#include "if_athn_usb_fw.h" + +unsigned int ifq_oactive = 0; + +static const STRUCT_USB_HOST_ID athn_usb_devs[] = { + { USB_VP(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_1) }, + { USB_VP(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_2) }, + { USB_VP(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_3)}, + { USB_VP(USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_1) }, + { USB_VP(USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_2) }, + { USB_VP(USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_3) }, + { USB_VP(USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_4) }, + { USB_VP(USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_5) }, + { USB_VP(USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_6) }, + { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_AR9271) }, + { USB_VP(USB_VENDOR_LITEON, USB_PRODUCT_LITEON_AR9271) }, + { USB_VP(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1100) }, + { USB_VP(USB_VENDOR_VIA, USB_PRODUCT_VIA_AR9271) }, + { USB_VPI(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_AR9280, ATHN_USB_FLAG_AR7010) }, + { USB_VPI(USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_AR9287, ATHN_USB_FLAG_AR7010) }, + { USB_VPI(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNDA3200, ATHN_USB_FLAG_AR7010) }, + { USB_VPI(USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_N5HBZ0000055, ATHN_USB_FLAG_AR7010) }, + { USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_UWABR100, ATHN_USB_FLAG_AR7010) }, + { USB_VPI(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9280, ATHN_USB_FLAG_AR7010) }, + { USB_VPI(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9287, ATHN_USB_FLAG_AR7010) } +}; +#define athn_usb_lookup(uaa) \ + (usbd_lookup_id_by_uaa(athn_usb_devs, sizeof(athn_usb_devs), uaa)) + +static device_probe_t athn_usb_match; +static device_attach_t athn_usb_attach; +static device_detach_t athn_usb_detach; + +// Temp +static void +ar9271_load_ani(struct athn_softc *sc) +{ + /* Write ANI registers. */ + AR_WRITE(sc, AR_PHY_DESIRED_SZ, 0x6d4000e2); + AR_WRITE(sc, AR_PHY_AGC_CTL1, 0x3139605e); + AR_WRITE(sc, AR_PHY_FIND_SIG, 0x7ec84d2e); + AR_WRITE(sc, AR_PHY_SFCORR_LOW, 0x06903881); + AR_WRITE(sc, AR_PHY_SFCORR, 0x5ac640d0); + AR_WRITE(sc, AR_PHY_CCK_DETECT, 0x803e68c8); + AR_WRITE(sc, AR_PHY_TIMING5, 0xd00a8007); + AR_WRITE(sc, AR_PHY_SFCORR_EXT, 0x05eea6d4); + AR_WRITE_BARRIER(sc); +} + +void athn_usb_attachhook(device_t self); +int athn_usb_open_pipes(struct athn_usb_softc *); +void athn_usb_close_pipes(struct athn_usb_softc *); +static int athn_alloc_list(struct athn_usb_softc *sc, struct athn_usb_data data[], + int ndata, int maxsz); +static int athn_free_list(struct athn_usb_softc *sc, struct athn_usb_data data[], + int ndata); +int athn_usb_alloc_rx_list(struct athn_usb_softc *); +void athn_usb_free_rx_list(struct athn_usb_softc *); +int athn_usb_alloc_tx_list(struct athn_usb_softc *); +void athn_usb_free_tx_list(struct athn_usb_softc *); +int athn_usb_alloc_tx_cmd(struct athn_usb_softc *); +void athn_usb_free_tx_cmd(struct athn_usb_softc *); +void athn_usb_task(void *, int); +void athn_usb_do_async(struct athn_usb_softc *, + void (*)(struct athn_usb_softc *, void *), void *, int); +void athn_usb_wait_async(struct athn_usb_softc *); +int athn_usb_htc_msg(struct athn_usb_softc *, uint16_t, void *, + int); +int athn_usb_htc_setup(struct athn_usb_softc *); +int athn_usb_htc_connect_svc(struct athn_usb_softc *, uint16_t, + uint8_t, uint8_t, uint8_t *); +int athn_usb_wmi_xcmd(struct athn_usb_softc *, uint16_t, void *, + int, void *); +int athn_usb_read_rom(struct athn_softc *); +uint32_t athn_usb_read(struct athn_softc *, uint32_t); +void athn_usb_write(struct athn_softc *, uint32_t, uint32_t); +void athn_usb_write_barrier(struct athn_softc *); +int athn_usb_media_change(struct ifnet *); +void athn_usb_next_scan(void *, int); +int athn_usb_newstate(struct ieee80211vap *, enum ieee80211_state, + int); +//void athn_usb_newstate_cb(struct athn_usb_softc *, void *); +void athn_usb_newassoc(struct ieee80211com *, + struct ieee80211_node *, int); +void athn_usb_newassoc_cb(struct athn_usb_softc *, void *); +struct ieee80211_node *athn_usb_node_alloc(struct ieee80211com *); +void athn_usb_count_active_sta(void *, struct ieee80211_node *); +void athn_usb_newauth_cb(struct athn_usb_softc *, void *); +int athn_usb_newauth(struct ieee80211com *, + struct ieee80211_node *, int, uint16_t); +void athn_usb_node_free(struct ieee80211com *, + struct ieee80211_node *); +void athn_usb_node_free_cb(struct athn_usb_softc *, void *); +int athn_usb_ampdu_tx_start(struct ieee80211com *, + struct ieee80211_node *, uint8_t); +void athn_usb_ampdu_tx_start_cb(struct athn_usb_softc *, void *); +void athn_usb_ampdu_tx_stop(struct ieee80211com *, + struct ieee80211_node *, uint8_t); +void athn_usb_ampdu_tx_stop_cb(struct athn_usb_softc *, void *); +void athn_usb_clean_nodes(void *, struct ieee80211_node *); +int athn_usb_create_node(struct athn_usb_softc *, + struct ieee80211_node *); +int athn_usb_node_set_rates(struct athn_usb_softc *, + struct ieee80211_node *); +int athn_usb_remove_node(struct athn_usb_softc *, + struct ieee80211_node *); +void athn_usb_rx_enable(struct athn_softc *); +int athn_set_chan(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *); +int athn_usb_switch_chan(struct athn_softc *, + struct ieee80211_channel *, struct ieee80211_channel *); +void athn_usb_updateedca(struct ieee80211com *); +void athn_usb_updateedca_cb(struct athn_usb_softc *, void *); +void athn_usb_updateslot(struct ieee80211com *); +void athn_usb_updateslot_cb(struct athn_usb_softc *, void *); +int athn_usb_set_key(struct ieee80211com *, + struct ieee80211_node *, struct ieee80211_key *); +void athn_usb_set_key_cb(struct athn_usb_softc *, void *); +void athn_usb_delete_key(struct ieee80211com *, + struct ieee80211_node *, struct ieee80211_key *); +void athn_usb_delete_key_cb(struct athn_usb_softc *, void *); +void athn_usb_bcneof(struct usb_xfer *xfer, void *priv, + usb_error_t status); +void athn_usb_swba(struct athn_usb_softc *); +void athn_usb_tx_status(void *, struct ieee80211_node *); +void athn_usb_rx_wmi_ctrl(struct athn_usb_softc *, uint8_t *, int); +void athn_usb_intr(struct usb_xfer *, void *, + usb_error_t); +void athn_usb_rx_radiotap(struct athn_softc *, struct mbuf *, + struct ar_rx_status *); +void athn_usb_rx_frame(struct athn_usb_softc *, struct mbuf */*, + struct mbuf_list **/); //MichalP: Uses mbuf_list which doesn't exist in FreeBSD +void athn_usb_rxeof(struct usb_xfer *, struct athn_usb_data*); +void athn_usb_txeof(struct usb_xfer *, struct athn_usb_data *); +int athn_usb_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, struct athn_usb_data *data, const struct ieee80211_bpf_params *params); +void athn_usb_start(struct ifnet *); +void athn_usb_watchdog(struct ifnet *); +int athn_usb_ioctl(struct ifnet *, u_long, caddr_t); +int athn_usb_init(struct ifnet *); +void athn_usb_stop(struct ifnet *); +void ar9271_load_ani(struct athn_softc *); +int ar5008_ccmp_decap(struct athn_softc *, struct mbuf *, + struct ieee80211_node *); +int ar5008_ccmp_encap(struct mbuf *, u_int, struct ieee80211_key *); + +/* Shortcut. */ +#define athn_usb_wmi_cmd(sc, cmd_id) \ + athn_usb_wmi_xcmd(sc, cmd_id, NULL, 0, NULL) + +/* Extern functions. */ +void athn_led_init(struct athn_softc *); +void athn_set_led(struct athn_softc *, int); +void athn_btcoex_init(struct athn_softc *); +void athn_set_rxfilter(struct athn_softc *, uint32_t); +int athn_reset(struct athn_softc *, int); +void athn_init_pll(struct athn_softc *, + const struct ieee80211_channel *); +int athn_set_power_awake(struct athn_softc *); +void athn_set_power_sleep(struct athn_softc *); +void athn_reset_key(struct athn_softc *, int); +int athn_set_key(struct ieee80211com *, struct ieee80211_node *, + struct ieee80211_key *); +void athn_delete_key(struct ieee80211com *, struct ieee80211_node *, + struct ieee80211_key *); +void athn_rx_start(struct athn_softc *); +void athn_set_sta_timers(struct athn_softc *); +void athn_set_hostap_timers(struct athn_softc *); +void athn_set_opmode(struct athn_softc *); +void athn_set_bss(struct athn_softc *, struct ieee80211_node *); +int athn_hw_reset(struct athn_softc *, struct ieee80211_channel *, + struct ieee80211_channel *, int); +void athn_updateedca(struct ieee80211com *); +void athn_updateslot(struct ieee80211com *); + +static void athn_if_intr_rx_callback(struct usb_xfer *xfer, usb_error_t error); +static void athn_if_intr_tx_callback(struct usb_xfer *xfer, usb_error_t error); +static void athn_if_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error); +static void athn_if_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error); + +static struct usb_config athn_if_config[ATHN_N_XFER] = { + [ATHN_BULK_TX] = { // MichalP: standard I/O + .type = UE_BULK, + .endpoint = AR_PIPE_TX_DATA, + .direction = UE_DIR_OUT, + .bufsize = 512, + .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, + .callback = athn_if_bulk_tx_callback, + .timeout = ATHN_USB_TX_TIMEOUT + }, // MichalP: standard I/O + [ATHN_BULK_RX] = { + .type = UE_BULK, + .endpoint = AR_PIPE_RX_DATA, + .direction = UE_DIR_IN, // .direction = UE_DIR_IN, + .bufsize = 512, + .flags = {.ext_buffer=1,.pipe_bof = 1,.short_xfer_ok = 1,}, + .callback = athn_if_bulk_rx_callback, + }, // MichalP: what the device sends to us (CMD replies) + [ATHN_BULK_IRQ] = { + .type = UE_INTERRUPT, + .endpoint = AR_PIPE_RX_INTR, + .direction = UE_DIR_IN, + .bufsize = 64, + .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, + .callback = athn_if_intr_rx_callback, + .interval = 1 + }, // MichalP: what we are sending to the device (CMDs) + [ATHN_BULK_CMD] = { + .type = UE_INTERRUPT, + .endpoint = AR_PIPE_TX_INTR, + .direction = UE_DIR_OUT, + .bufsize = 64, + .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, + .callback = athn_if_intr_tx_callback, + .timeout = 5000, /* ms */ + .interval = 1 + } +}; + +#define INFSLP UINT64_MAX +#define NSEC_PER_SEC 1000000000 + +// TODO MichalP: we use msleep with mtx so this could be obsolete +#if OpenBSD_ONLY +int +tsleep_nsec(const void *ident, int priority, const char *wmesg, + uint64_t nsecs) +{ + uint64_t to_ticks; + int tick_nsec = (NSEC_PER_SEC + hz / 2) / hz; + + if (nsecs == INFSLP) + return tsleep(ident, priority, wmesg, 0); +#ifdef DIAGNOSTIC + if (nsecs == 0) { + log(LOG_WARNING, + "%s: %s[%d]: %s: trying to sleep zero nanoseconds\n", + __func__, curproc->p_p->ps_comm, curproc->p_p->ps_pid, + wmesg); + } +#endif + /* + * We want to sleep at least nsecs nanoseconds worth of ticks. + * + * - Clamp nsecs to prevent arithmetic overflow. + * + * - Round nsecs up to account for any nanoseconds that do not + * divide evenly into tick_nsec, otherwise we'll lose them to + * integer division in the next step. We add (tick_nsec - 1) + * to keep from introducing a spurious tick if there are no + * such nanoseconds, i.e. nsecs % tick_nsec == 0. + * + * - Divide the rounded value to a count of ticks. We divide + * by (tick_nsec + 1) to discard the extra tick introduced if, + * before rounding, nsecs % tick_nsec == 1. + * + * - Finally, add a tick to the result. We need to wait out + * the current tick before we can begin counting our interval, + * as we do not know how much time has elapsed since the + * current tick began. + */ + nsecs = MIN(nsecs, UINT64_MAX - tick_nsec); + to_ticks = (nsecs + tick_nsec - 1) / (tick_nsec + 1) + 1; + if (to_ticks > INT_MAX) + to_ticks = INT_MAX; + return tsleep(ident, priority, wmesg, (int)to_ticks); +} +#endif + +static device_method_t athn_usb_methods[] = { + DEVMETHOD(device_probe, athn_usb_match), + DEVMETHOD(device_attach, athn_usb_attach), + DEVMETHOD(device_detach, athn_usb_detach), + + DEVMETHOD_END +}; + +static driver_t athn_usb_driver = { + .name = "athn", + .methods = athn_usb_methods, + .size = sizeof(struct athn_usb_softc) +}; + +/* Temporary to nofiy that the module was loaded TODO MichalP: this can be removed at somepoint*/ +static int +athn_usb_load(struct module *m, int what, void *arg) +{ + int error = 0; + + switch (what) { + case MOD_LOAD: + uprintf("Athn KLD loaded.\n"); + break; + case MOD_UNLOAD: + uprintf("Athn KLD unloaded.\n"); + break; + default: + error = EOPNOTSUPP; + break; + } + return(error); +} + +DRIVER_MODULE(athn_usb, uhub, athn_usb_driver, athn_usb_load, NULL); +MODULE_DEPEND(athn_usb, usb, 1, 1, 1); +MODULE_DEPEND(athn_usb, wlan, 1, 1, 1); +MODULE_VERSION(athn_usb, 1); +USB_PNP_HOST_INFO(athn_usb_devs); + +static int +athn_usb_match(device_t self) +{ + struct usb_attach_arg *uaa = device_get_ivars(self); + int result = 0; + + if (uaa->usb_mode != USB_MODE_HOST) + return (ENXIO); + if (uaa->info.bConfigIndex != 0) + return (ENXIO); + if (uaa->info.bIfaceIndex != 0) + return (ENXIO); + + result = athn_usb_lookup(uaa); + + printf("athn_usb_lookup called with result %d \n", result); + + if (result == 0) { + printf("serial: %s \n", usb_get_serial(uaa->device)); + printf("product: %s-%s \n", usb_get_manufacturer(uaa->device), + usb_get_product(uaa->device)); + printf("ProductID: 0x%x \n", uaa->info.idProduct); + printf("VendorID: 0x%x \n", uaa->info.idVendor); + } + + return result; +} + +static int +athn_usb_attach(device_t self) +{ + struct usb_attach_arg *uaa = device_get_ivars(self); + struct athn_usb_softc *usc = device_get_softc(self); + struct athn_softc *sc = &usc->sc_sc; + struct ieee80211com *ic = &sc->sc_ic; + usb_error_t error; + struct usb_endpoint *ep, *ep_end; + + device_set_usb_desc(self); + usc->sc_udev = uaa->device; + sc->sc_dev = self; + ic->ic_name = device_get_nameunit(self); + + usc->flags = uaa->driver_info; + sc->flags |= ATHN_FLAG_USB; +#ifdef notyet + /* Check if it is a combo WiFi+Bluetooth (WB193) device. */ + if (strncmp(product, "wb193", 5) == 0) + sc->flags |= ATHN_FLAG_BTCOEX3WIRE; +#endif + + sc->ops.read = athn_usb_read; + sc->ops.write = athn_usb_write; + sc->ops.write_barrier = athn_usb_write_barrier; + + mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, MTX_DEF); + + // MichalP calib_to timeout missing don't know how to put it all together + TIMEOUT_TASK_INIT(taskqueue_thread, &sc->scan_to, 0, athn_usb_next_scan, sc); + TASK_INIT(&sc->sc_task, 0, athn_usb_task, sc); + mbufq_init(&sc->sc_snd, ifqmaxlen); + + error = usbd_transfer_setup(uaa->device, &uaa->info.bIfaceIndex, usc->sc_xfer, athn_if_config, + ATHN_N_XFER, usc, &sc->sc_mtx); + if (error) { + device_printf(sc->sc_dev, + "could not allocate USB transfers, err=%s\n", + usbd_errstr(error)); + mtx_destroy(&sc->sc_mtx); + return error; + } + + // TODO MichalP just for debug purposes can be removed + ep = usc->sc_udev->endpoints; + ep_end = usc->sc_udev->endpoints + usc->sc_udev->endpoints_max; + for (; ep != ep_end; ep++) { + uint8_t eaddr; + + eaddr = ep->edesc->bEndpointAddress; + device_printf(sc->sc_dev, "%s: endpoint: addr %u, direction %s, endpoint: %p \n", __func__, + UE_GET_ADDR(eaddr), UE_GET_DIR(eaddr) == UE_DIR_OUT ? "output" : "input", ep); + } + + if (athn_usb_open_pipes(usc) != 0) + return error; + + /* Allocate xfer for firmware commands. */ + if (athn_usb_alloc_tx_cmd(usc) != 0) + return error; + + athn_usb_attachhook(self); + + return 0; +} + +static int +athn_usb_detach(device_t self) +{ + struct athn_usb_softc *usc = device_get_softc(self); + struct athn_softc *sc = &usc->sc_sc; + + if (usc->sc_athn_attached) + athn_detach(sc); + + /* Wait for all async commands to complete. */ + athn_usb_wait_async(usc); + + usbd_transfer_unsetup(usc->sc_xfer, ATHN_N_XFER); + + /* Abort and close Tx/Rx pipes. */ + athn_usb_close_pipes(usc); + + /* Free Tx/Rx buffers. */ + athn_usb_free_tx_cmd(usc); + athn_usb_free_tx_list(usc); + athn_usb_free_rx_list(usc); + + athn_usb_unload_firmware(); + printf("athn_usb_detach called \n"); + return (0); +} + +static struct ieee80211vap * +athn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, + enum ieee80211_opmode opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct ieee80211vap *vap; + struct athn_vap *uvp; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) + return (NULL); + + uvp = malloc(sizeof(struct athn_vap), M_80211_VAP, M_WAITOK | M_ZERO); + vap = &uvp->vap; + + if (ieee80211_vap_setup(ic, vap, name, unit, opmode, + flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) { + /* out of memory */ + free(uvp, M_80211_VAP); + return (NULL); + } + + /* override state transition machine */ + uvp->newstate = vap->iv_newstate; + vap->iv_newstate = athn_usb_newstate; + + vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_8; + vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K; + + ieee80211_ratectl_init(vap); + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, + ieee80211_media_status, mac); + ic->ic_opmode = opmode; + + return (vap); +} + +static void +athn_vap_delete(struct ieee80211vap *vap) +{ + struct athn_vap *uvp = ATHN_VAP(vap); + + ieee80211_ratectl_deinit(vap); + ieee80211_vap_detach(vap); + free(uvp, M_80211_VAP); +} + +static int +athn_usb_get_fw_ver(struct athn_softc *sc, struct ar_wmi_fw_version *version) +{ + struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; + struct ar_wmi_fw_version cmd_rsp; + int error; + + device_printf(sc->sc_dev, "%s: called \n", __func__); + + ATHN_LOCK(&usc->sc_sc); + error = athn_usb_wmi_xcmd(usc, AR_WMI_GET_FW_VERSION, NULL, 0, version); + ATHN_UNLOCK(&usc->sc_sc); + + version->major = bswap16(version->major); + version->minor = bswap16(version->minor); + + if (error != 0) { + device_printf(sc->sc_dev, "%s: error = %d\n", __func__, error); + version->major = 0; + version->minor = 0; + } + + return error; +} + +/* Read fw version from module and compare it with passed image version */ +static int +athn_usb_verify_fw_ver(struct athn_softc *sc, struct ar_wmi_fw_version *img_ver) +{ + struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; + struct ar_wmi_fw_version fw_ver; + int error; + + device_printf(sc->sc_dev, "%s: called \n", __func__); + + error = athn_usb_get_fw_ver(sc, &fw_ver); + + if ((img_ver->major != fw_ver.major) || + (img_ver->minor != fw_ver.minor)) { + device_printf(sc->sc_dev, "%s: Image fw version %d.%d differs from module fw version %d.%d\n", + __func__, img_ver->major, img_ver->minor, fw_ver.major, fw_ver.minor); + return -1; + } + return error; +} + +static void +athn_set_channel(struct ieee80211com *ic) +{ + struct athn_softc *sc = ic->ic_softc; + + ATHN_LOCK(sc); + (void) athn_usb_switch_chan(sc, ic->ic_curchan, NULL); + ATHN_UNLOCK(sc); +} + +static struct athn_usb_data * +_athn_getbuf(struct athn_softc *sc) +{ + struct athn_usb_data *bf; + struct athn_usb_softc *usc = sc->sc_usc; + + bf = STAILQ_FIRST(&usc->sc_tx_inactive); + if (bf != NULL) + STAILQ_REMOVE_HEAD(&usc->sc_tx_inactive, next); + else + bf = NULL; + /* XXX bzero? */ + return (bf); +} + +static struct athn_usb_data * +athn_getbuf(struct athn_softc *sc) +{ + struct athn_usb_data *bf; + + ATHN_ASSERT_LOCKED(sc); + + bf = _athn_getbuf(sc); + return (bf); +} + +static void +athn_freebuf(struct athn_softc *sc, struct athn_usb_data *bf) +{ + struct athn_usb_softc *usc = sc->sc_usc; + + ATHN_ASSERT_LOCKED(sc); + STAILQ_INSERT_TAIL(&usc->sc_tx_inactive, bf, next); +} + +static int +athn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, + const struct ieee80211_bpf_params *params) +{ + struct ieee80211com *ic= ni->ni_ic; + struct athn_softc *sc = ic->ic_softc; + struct athn_usb_softc *usc = sc->sc_usc; + struct athn_usb_data *bf = NULL; + int error = 0; + + // Probably not needed + /* Don't transmit if we're not running */ + ATHN_LOCK(sc); + // if (!sc->sc_running) { + // error = ENETDOWN; + // goto error; + // } + + bf = athn_getbuf(sc); + if (bf == NULL) { + error = ENOBUFS; + goto error; + } + + if (athn_usb_tx(sc, m, ni, bf, params) != 0) { + error = EIO; + goto error; + } + + ATHN_UNLOCK(sc); + return (0); +error: + if (bf) + athn_freebuf(sc, bf); + ATHN_UNLOCK(sc); + m_freem(m); + return (error); +} + +static void +athn_tx_start(struct athn_softc *sc) +{ + + taskqueue_enqueue(taskqueue_thread, &sc->sc_task); +} + +static int +athn_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct athn_softc *sc = ic->ic_softc; + int error; + + ATHN_LOCK(sc); + // if (! sc->sc_running) { + // OTUS_UNLOCK(sc); + // return (ENXIO); + // } + + /* XXX TODO: handle fragments */ + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + device_printf(sc->sc_dev, "%s: mbufq_enqueue failed: %d\n", __func__, error); + ATHN_UNLOCK(sc); + return (error); + } + ATHN_UNLOCK(sc); + + /* Kick TX */ + athn_tx_start(sc); + + return (0); +} + +void +athn_usb_attachhook(device_t self) +{ + struct athn_usb_softc *usc = device_get_softc(self); + struct athn_softc *sc = &usc->sc_sc; + sc->sc_usc = usc; + struct ar_wmi_fw_version img_ver; + struct athn_ops *ops = &sc->ops; + uint32_t val = 104; + uint32_t in, out; + + struct ieee80211com *ic = &sc->sc_ic; +#ifdef notyet + + struct ifnet *ifp = &ic->ic_if; +#endif + int s, i, error; + + /* Load firmware. */ + error = athn_usb_load_firmware(usc, &img_ver); + if (error != 0) { + printf("Could not load firmware\n"); + return; + } + DELAY(1000 *1000); + printf("FW loaded\n"); + + // TODO MichalP: this can be used as a starting point for echo command or firmware command +// ATHN_LOCK(&usc->sc_sc); +// device_printf(sc->sc_dev, " %s:val = %d\n", __func__, val); +// NOTE: command below is invalid because athn_usb_read has different arguments but let's keep that note about echo +// val = athn_usb_read(sc, AR_WMI_CMD_ECHO); +// device_printf(sc->sc_dev, "%s: returned val = %d\n", __func__, val); +// val = *(uint32_t*)usc->obuf; +// device_printf(sc->sc_dev, "%s: casted val = %d\n", __func__, val); +// ATHN_UNLOCK(&usc->sc_sc); +// +// return; + + device_printf(sc->sc_dev, "%s: before athn_usb_htc_setup\n", __func__); + + /* Setup the host transport communication interface. */ + error = athn_usb_htc_setup(usc); + if (error != 0) + return; + + device_printf(sc->sc_dev, "%s: after athn_usb_htc_setup\n", __func__); + +// TODO: MikolajF:I couldn't read a FW version before the firmware upload because +// the module never responded to the WMI request, even if I moved the htc setup +// before loading the FW. I don't know why, but checking it at this point is not +// useful and adds to the initialization time. It's not critical and can be +// investigated or ignored in the future. +#if 0 + error = athn_usb_verify_fw_ver(sc, &img_ver); + if (error != 0) + return; +#endif + + /* We're now ready to attach the bus agnostic driver. */ + // TODO: MichalP needs proper FreeBSD adaptation because this uses code that is + // stubbed and/or commented + ic->ic_softc = sc; + + error = athn_like_otus_attach(sc); + if (error != 0) { + return; + } + + // ic->ic_newstate = athn_usb_newstate; + ic->ic_vap_create = athn_vap_create; + ic->ic_vap_delete = athn_vap_delete; + ic->ic_set_channel = athn_set_channel; + ic->ic_raw_xmit = athn_raw_xmit; + + // TODO + // ifp->if_ioctl = athn_usb_ioctl; + // ifp->if_start = athn_usb_start; + + usc->sc_athn_attached = 1; +#if OpenBSD_IEEE80211_API + /* Override some operations for USB. */ + ifp->if_ioctl = athn_usb_ioctl; + ifp->if_start = athn_usb_start; + // TODO no member named 'if_watchdog' in 'struct ifnet' + // ifp->if_watchdog = athn_usb_watchdog; + ic->ic_node_alloc = athn_usb_node_alloc; + ic->ic_newauth = athn_usb_newauth; + ic->ic_newassoc = athn_usb_newassoc; +#ifndef IEEE80211_STA_ONLY + usc->sc_node_free = ic->ic_node_free; + ic->ic_node_free = athn_usb_node_free; +#endif + ic->ic_updateslot = athn_usb_updateslot; + ic->ic_updateedca = athn_usb_updateedca; + ic->ic_set_key = athn_usb_set_key; + ic->ic_delete_key = athn_usb_delete_key; + ic->ic_vap_create = athn_vap_create; + ic->ic_vap_delete = athn_vap_delete; + ic->ic_ampdu_tx_start = athn_usb_ampdu_tx_start; + ic->ic_ampdu_tx_stop = athn_usb_ampdu_tx_stop; + ic->ic_newstate = athn_usb_newstate; + + ic->ic_media.ifm_change_cb = athn_usb_media_change; + + +#endif + ATHN_LOCK(sc); + /* Reset HW key cache entries. */ + for (i = 0; i < sc->kc_entries; i++) + athn_reset_key(sc, i); + + ops->enable_antenna_diversity(sc); + + ops->rx_enable = athn_usb_rx_enable; + ATHN_UNLOCK(sc); + +#ifdef ATHN_BT_COEXISTENCE + /* Configure bluetooth coexistence for combo chips. */ + if (sc->flags & ATHN_FLAG_BTCOEX) + athn_btcoex_init(sc); +#endif + /* Configure LED. */ +// #if OpenBSD_ONLY + ATHN_LOCK(sc); + athn_led_init(sc); + ATHN_UNLOCK(sc); +// #endif +} + +int +athn_usb_open_pipes(struct athn_usb_softc *usc) +{ + struct athn_softc *sc = &usc->sc_sc; + usb_error_t error; +#if OpenBSD_ONLY + /* Init host async commands ring. */ + usc->cmdq.cur = usc->cmdq.next = usc->cmdq.queued = 0; +#endif + /* Allocate Tx/Rx buffers. */ + if((error = athn_usb_alloc_rx_list(usc)) != 0) { + device_printf(sc->sc_dev, "%s: could not allocate Tx xfers\n", + __func__); + goto fail; + } + if ((error = athn_usb_alloc_tx_list(usc)) != 0) { + device_printf(sc->sc_dev, "%s: could not allocate Tx xfers\n", + __func__); + goto fail; + } +#if OpenBSD_ONLY + /* Steal one buffer for beacons. */ + usc->tx_bcn = TAILQ_FIRST(&usc->tx_free_list); + TAILQ_REMOVE(&usc->tx_free_list, usc->tx_bcn, next); +#endif + + ATHN_LOCK(sc); + usbd_transfer_start(usc->sc_xfer[ATHN_BULK_RX]); + usbd_transfer_start(usc->sc_xfer[ATHN_BULK_IRQ]); + ATHN_UNLOCK(sc); + return 0; + + fail: + athn_usb_close_pipes(usc); + return (error); +} + +void +athn_usb_close_pipes(struct athn_usb_softc *usc) +{ + struct athn_softc *sc = &usc->sc_sc; + + ATHN_LOCK(sc); + athn_usb_free_rx_list(usc); + athn_usb_free_tx_list(usc); + athn_usb_free_tx_cmd(usc); + ATHN_UNLOCK(sc); +} + +static int +athn_alloc_list(struct athn_usb_softc *usc, struct athn_usb_data data[], + int ndata, int maxsz) +{ + struct athn_softc *sc = &usc->sc_sc; + int i, error; + + for (i = 0; i < ndata; i++) { + struct athn_usb_data *dp = &data[i]; + dp->usc = usc; + // TODO MichalP might be needed not sure +// dp->m = NULL; + dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT | M_ZERO); + if (dp->buf == NULL) { + device_printf(sc->sc_dev, + "could not allocate buffer\n"); + error = ENOMEM; + goto fail; + } + + // TODO MichalP need IEEE80211 api implemented + //dp->ni = NULL; + } + + return (0); +fail: + athn_free_list(usc, data, ndata); + return (error); +} + +static int +athn_free_list(struct athn_usb_softc *usc, struct athn_usb_data data[], int ndata) +{ + int i; + + for (i = 0; i < ndata; i++) { + struct athn_usb_data *dp = &data[i]; + + if (dp->buf != NULL) { + free(dp->buf, M_USBDEV); + dp->buf = NULL; + } +// TODO MichalP need IEEE80211 api implemented +// if (dp->ni != NULL) { +// ieee80211_free_node(dp->ni); +// dp->ni = NULL; +// } + } + return 0; +} + +int +athn_usb_alloc_rx_list(struct athn_usb_softc *usc) +{ + int i, error; + + error = athn_alloc_list(usc, usc->rx_data, ATHN_USB_RX_LIST_COUNT, + ATHN_USB_RXBUFSZ); + + STAILQ_INIT(&usc->sc_rx_active); + STAILQ_INIT(&usc->sc_rx_inactive); + + for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) + STAILQ_INSERT_HEAD(&usc->sc_rx_inactive, &usc->rx_data[i], next); + + return (error); +} + +void +athn_usb_free_rx_list(struct athn_usb_softc *usc) +{ + int i; + + STAILQ_INIT(&usc->sc_rx_inactive); + STAILQ_INIT(&usc->sc_rx_active); + + athn_free_list(usc, usc->rx_data, ATHN_USB_RX_LIST_COUNT); +} + +int +athn_usb_alloc_tx_list(struct athn_usb_softc *usc) +{ + int i, error; + + error = athn_alloc_list(usc, usc->tx_data, ATHN_USB_TX_LIST_COUNT, + ATHN_USB_TXBUFSZ); + if (error != 0) + return (error); + + STAILQ_INIT(&usc->sc_tx_inactive); + + for (i = 0; i != ATHN_N_XFER; i++) { + STAILQ_INIT(&usc->sc_tx_active[i]); + STAILQ_INIT(&usc->sc_tx_pending[i]); + } + + for (i = 0; i < ATHN_USB_TX_LIST_COUNT; i++) { + STAILQ_INSERT_HEAD(&usc->sc_tx_inactive, &usc->tx_data[i], next); + } + + return (0); +} + +void +athn_usb_free_tx_list(struct athn_usb_softc *usc) +{ + int i; + + STAILQ_INIT(&usc->sc_tx_inactive); + + for (i = 0; i != ATHN_N_XFER; i++) { + STAILQ_INIT(&usc->sc_tx_active[i]); + STAILQ_INIT(&usc->sc_tx_pending[i]); + } + + athn_free_list(usc, usc->tx_data, ATHN_USB_TX_LIST_COUNT); +} + +int +athn_usb_alloc_tx_cmd(struct athn_usb_softc *usc) +{ + struct athn_usb_data *data; + int i, error = 0; + + error = athn_alloc_list(usc, usc->tx_cmd, ATHN_USB_HOST_CMD_RING_COUNT, + ATHN_USB_TXCMDSZ); + if (error != 0) + return (error); + + STAILQ_INIT(&usc->sc_cmd_active); + STAILQ_INIT(&usc->sc_cmd_inactive); + STAILQ_INIT(&usc->sc_cmd_pending); + STAILQ_INIT(&usc->sc_cmd_waiting); + + for (i = 0; i < ATHN_USB_HOST_CMD_RING_COUNT; i++) + STAILQ_INSERT_HEAD(&usc->sc_cmd_inactive, &usc->tx_cmd[i], next); + + return (0); +} + +void +athn_usb_free_tx_cmd(struct athn_usb_softc *usc) +{ + STAILQ_INIT(&usc->sc_cmd_active); + STAILQ_INIT(&usc->sc_cmd_inactive); + STAILQ_INIT(&usc->sc_cmd_pending); + STAILQ_INIT(&usc->sc_cmd_waiting); + + athn_free_list(usc, usc->tx_cmd, ATHN_USB_HOST_CMD_RING_COUNT); +} + +char *state2Str(int state) { + switch (state) { + case USB_ST_SETUP: + return "USB_ST_SETUP"; + case USB_ST_TRANSFERRED: + return "USB_ST_TRANSFERRED"; + case USB_ST_ERROR: + return "USB_ST_ERROR"; + default: + return "state2Str UNKNOWN"; + } +} + + +char * epType_str(uint8_t bmAttributes) { + switch(bmAttributes) { + case UE_CONTROL: + return "UE_CONTROL"; + case UE_ISOCHRONOUS: + return "UE_ISOCHRONOUS"; + case UE_BULK: + return "UE_BULK"; + case UE_INTERRUPT: + return "UE_INTERRUPT"; + default: + return "UNKNOWN"; + } +} + +static boolean_t +athn_htc_rx_handle(struct athn_usb_softc *usc, uint8_t *buf, int actlen) +{ + struct ar_htc_msg_hdr *msg; + uint16_t msg_id; + + // Endpoint 0 carries HTC messages. + if (actlen < sizeof(*msg)) { + printf("TTTT: htc->flags & AR_HTC_FLAG_TRAILER\n"); + return TRUE; + } + + msg = (struct ar_htc_msg_hdr *)buf; + msg_id = betoh16(msg->msg_id); + printf("TTTT: Rx HTC msg_id %d, wait_msg_id %d \n", msg_id, usc->wait_msg_id); + switch (msg_id) { + case AR_HTC_MSG_READY: + if (usc->wait_msg_id != msg_id) + break; + usc->wait_msg_id = 0; + wakeup(&usc->wait_msg_id); + break; + case AR_HTC_MSG_CONN_SVC_RSP: + if (usc->wait_msg_id != msg_id) + break; + if (usc->msg_conn_svc_rsp != NULL) { + memcpy(usc->msg_conn_svc_rsp, &msg[1], + sizeof(struct ar_htc_msg_conn_svc_rsp)); + } + usc->wait_msg_id = 0; + wakeup(&usc->wait_msg_id); + break; + case AR_HTC_MSG_CONF_PIPE_RSP: + if (usc->wait_msg_id != msg_id) + break; + usc->wait_msg_id = 0; + wakeup(&usc->wait_msg_id); + break; + default: + printf("HTC message %d ignored\n", msg_id); + break; + } + return FALSE; +} + +// TODO: probably there is something missing here +static void +athn_if_intr_rx_callback(struct usb_xfer *xfer, usb_error_t error) +{ + struct athn_usb_softc *usc = usbd_xfer_softc(xfer); + struct ar_htc_frame_hdr *htc; + uint8_t *buf; + + int actlen, sumlen; + int state = USB_GET_STATE(xfer); + char *state_str = state2Str(state); + + usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); + + printf("TTTT: INTR RX Xfer callback: error = %s, state = %s, actlen = %d, " + "sumlen = %d, endpoint = 0x%lx\n", + usbd_errstr(error), state_str, actlen, sumlen, (long)xfer->endpoint); + + switch(state) { + case USB_ST_TRANSFERRED: + { + printf("TTTT: INTR RX Xfer state USB_ST_TRANSFERRED\n"); + + buf = usbd_xfer_get_frame_buffer(xfer, 0); + if (actlen >= 4 && *(uint32_t *)buf == htobe32(0x00c60000)) { + buf += 4; + actlen -= 4; + } + if ((actlen < sizeof(*htc))) + return; + + htc = (struct ar_htc_frame_hdr *)buf; + // Skip HTC header. + buf += sizeof(*htc); + actlen -= sizeof(*htc); + + if (htc->endpoint_id == 0) { + if (athn_htc_rx_handle(usc, buf, actlen)) + break; + } else { + printf("TTTT: htc->endpoint_id != 0\n"); + if (htc->endpoint_id != usc->ep_ctrl) { + printf("TTTT: htc->endpoint_id != usc->ep_ctrl\n"); + return; + } + + /// Remove trailer if present. + if (htc->flags & AR_HTC_FLAG_TRAILER) { + printf("TTTT: htc->flags & AR_HTC_FLAG_TRAILER\n"); + if (actlen < htc->control[0]) { + printf("TTTT: actlen < htc->control[0]\n"); + return; + } + + actlen -= htc->control[0]; + } + athn_usb_rx_wmi_ctrl(usc, buf, actlen); + } + } + /* FALLTHROUGH */ + case USB_ST_SETUP: + printf("USB_ST_SETUP called\n"); + usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); + usbd_transfer_submit(xfer); + break; + default: /* Error */ + printf("TTTT: INTR RX Xfer: error\n"); + break; + } + return; +} + +static void +athn_if_intr_tx_callback(struct usb_xfer *xfer, usb_error_t error) +{ + struct athn_usb_data *cmd; + struct athn_usb_softc *usc = usbd_xfer_softc(xfer); + struct athn_softc *sc = &usc->sc_sc; + + int actlen; + int state = USB_GET_STATE(xfer); + char *state_str = state2Str(state); + + ATHN_ASSERT_LOCKED(sc); + + usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); + + // MichalP: Debuginfo + printf("TTTT: INTR TX Xfer callback: error = %s, state = %s, actlen = %d, endpoint = 0x%lx\n", + usbd_errstr(error), state_str, actlen, (long)xfer->endpoint); + + switch(state) { + case USB_ST_TRANSFERRED: + cmd = STAILQ_FIRST(&usc->sc_cmd_active); + device_printf(sc->sc_dev, "%s: continue with USB_ST_TRANSFERRED cmd: %p\n", __func__, cmd); + if (cmd == NULL) + goto tr_setup; + device_printf(sc->sc_dev, "%s: transfer done cmd: %p\n", __func__, cmd); + STAILQ_REMOVE_HEAD(&usc->sc_cmd_active, next); + // MichalP TODO: this still needs some thinking maybe separate function + // different object that the thread sleeps on (cmd?) + if ((usc->wait_msg_id == AR_HTC_MSG_CONN_SVC_RSP) || + (usc->wait_msg_id == AR_WMI_CMD_MSG)) { + device_printf(sc->sc_dev, "%s: we are waiting for a response cmd: %p\n", __func__, cmd); + STAILQ_INSERT_TAIL(&usc->sc_cmd_waiting, cmd, next); + } else { + device_printf(sc->sc_dev, "%s: we DONT wait for response cmd: %p\n", __func__, cmd); + wakeup(&usc->wait_msg_id); + STAILQ_INSERT_TAIL(&usc->sc_cmd_inactive, cmd, next); + } + if (usc->wait_msg_id == AR_WMI_CMD_MSG) + STAILQ_INSERT_TAIL(&usc->sc_cmd_inactive, cmd, next); + /* FALLTHROUGH */ + case USB_ST_SETUP: +tr_setup: + cmd = STAILQ_FIRST(&usc->sc_cmd_pending); + if (cmd == NULL) { + device_printf(sc->sc_dev, "%s: empty pending queue cmd: %p\n", __func__, cmd); + return; + } + // device_printf(sc->sc_dev, "%s: continue with USB_ST_SETUP cmd: %p\n", __func__, cmd); + STAILQ_REMOVE_HEAD(&usc->sc_cmd_pending, next); + STAILQ_INSERT_TAIL(&usc->sc_cmd_active, cmd, next); + usbd_xfer_set_frame_data(xfer, 0, cmd->buf, cmd->buflen); + // device_printf(sc->sc_dev, "%s: submitting transfer %p; buf=%p, buflen=%d\n", + // __func__, cmd, cmd->buf, cmd->buflen); + usbd_transfer_submit(xfer); + break; + default: + cmd = STAILQ_FIRST(&usc->sc_cmd_active); + // device_printf(sc->sc_dev, "%s: continue with default %p\n", __func__, usc); + if (cmd != NULL) { + device_printf(sc->sc_dev, "%s: cmd not NULL %p\n", __func__, usc); + STAILQ_REMOVE_HEAD(&usc->sc_cmd_active, next); +// if (cmd->odata) { +// STAILQ_INSERT_TAIL(&usc->sc_cmd_waiting, cmd, next_cmd); +// } else { +// wakeup(cmd); +// otus_free_txcmd(sc, cmd); +// } + } + if (error != USB_ERR_CANCELLED) { + usbd_xfer_set_stall(xfer); + goto tr_setup; + } + break; + } +} + +// TODO: probably there is something missing here +static void +athn_if_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) +{ + struct athn_usb_softc *usc = usbd_xfer_softc(xfer); + struct athn_softc *sc = &usc->sc_sc; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_frame *wh; + struct ieee80211_node *ni; + struct athn_usb_data *data; + + int actlen; + int state = USB_GET_STATE(xfer); + char *state_str = state2Str(state); + + ATHN_ASSERT_LOCKED(sc); + + usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); + + // MichalP: Debuginfo + printf("TTTT: BULK RX Xfer callback: error = %s, state = %s, actlen = %d, endpoint = 0x%lx\n", + usbd_errstr(error), state_str, actlen, (long)xfer->endpoint); + + switch(state) { + case USB_ST_TRANSFERRED: + device_printf(sc->sc_dev, "%s: USB_ST_TRANSFERRED called \n", __func__); + data = STAILQ_FIRST(&usc->sc_rx_active); + if (data == NULL) + goto tr_setup; + STAILQ_REMOVE_HEAD(&usc->sc_rx_active, next); + athn_usb_rxeof(xfer, data); + STAILQ_INSERT_TAIL(&usc->sc_rx_inactive, data, next); + /* FALLTHROUGH */ + case USB_ST_SETUP: + device_printf(sc->sc_dev, "%s: USB_ST_SETUP called \n", __func__); + tr_setup: + device_printf(sc->sc_dev, "%s: USB_ST_SETUP after goto called \n", __func__); + data = STAILQ_FIRST(&usc->sc_rx_inactive); + if (data == NULL) { + //KASSERT(m == NULL, ("mbuf isn't NULL")); + return; + } + STAILQ_REMOVE_HEAD(&usc->sc_rx_inactive, next); + STAILQ_INSERT_TAIL(&usc->sc_rx_active, data, next); + usbd_xfer_set_frame_data(xfer, 0, data->buf, + usbd_xfer_max_len(xfer)); + usbd_transfer_submit(xfer); + break; + default: + device_printf(sc->sc_dev, "%s: default called \n", __func__); + /* needs it to the inactive queue due to a error. */ + data = STAILQ_FIRST(&usc->sc_rx_active); + if (data != NULL) { + STAILQ_REMOVE_HEAD(&usc->sc_rx_active, next); + STAILQ_INSERT_TAIL(&usc->sc_rx_inactive, data, next); + } + if (error != USB_ERR_CANCELLED) { + usbd_xfer_set_stall(xfer); + counter_u64_add(ic->ic_ierrors, 1); + goto tr_setup; + } + break; + } +} + +static void +athn_if_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) +{ + uint8_t which = ATHN_BULK_TX; + struct athn_usb_softc *usc = usbd_xfer_softc(xfer); + struct athn_softc *sc = &usc->sc_sc; + struct ieee80211com *ic = &sc->sc_ic; + struct athn_usb_data *data; + + ATHN_ASSERT_LOCKED(sc); + + int actlen; + int state = USB_GET_STATE(xfer); + char *state_str = state2Str(state); + + usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); + + // printf("TTTT: BULK TX Xfer callback: error = %s, state = %s, actlen = %d, endpoint = 0x%lx\n", + // usbd_errstr(error), state_str, actlen, (long)xfer->endpoint); + + switch(state) { + case USB_ST_TRANSFERRED: + data = STAILQ_FIRST(&usc->sc_tx_active[which]); + if (data == NULL) + goto tr_setup; + // device_printf(sc->sc_dev, "%s: transfer done %p\n", __func__, data); + STAILQ_REMOVE_HEAD(&usc->sc_tx_active[which], next); + athn_usb_txeof(xfer, data); + athn_freebuf(sc, data); + STAILQ_INSERT_TAIL(&usc->sc_tx_inactive, data, next); + case USB_ST_SETUP: + tr_setup: + data = STAILQ_FIRST(&usc->sc_tx_pending[which]); + if (data == NULL) { + device_printf(sc->sc_dev, "%s: empty pending queue sc %p\n", __func__, sc); + usc->sc_tx_n_active = 0; + } + // STAILQ_REMOVE_HEAD(&usc->sc_tx_pending[which], next); + STAILQ_INSERT_TAIL(&usc->sc_tx_active[which], data, next); + usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen); + // device_printf(sc->sc_dev, "%s: submitting transfer %p\n", __func__, data); + usbd_transfer_submit(xfer); + usc->sc_tx_n_active++; + break; + default: + data = STAILQ_FIRST(&usc->sc_tx_active[which]); + if (data != NULL) { + STAILQ_REMOVE_HEAD(&usc->sc_tx_active[which], next); + athn_usb_txeof(xfer, data); + STAILQ_INSERT_TAIL(&usc->sc_tx_inactive, data, next); + } + counter_u64_add(ic->ic_oerrors, 1); + + if (error != USB_ERR_CANCELLED) { + usbd_xfer_set_stall(xfer); + goto tr_setup; + } + break; + } + + taskqueue_enqueue(taskqueue_thread, &sc->sc_task); +} + +// TODO? +void +athn_usb_task(void *arg, int pending) +{ +#ifdef otus + struct athn_usb_softc *usc = arg; + struct athn_usb_host_cmd_ring *ring = &usc->cmdq; + struct athn_usb_host_cmd *cmd; + int s; + + // lock + + /* Process host commands. */ + while (ring->next != ring->cur) { + cmd = &ring->cmd[ring->next]; + /* Invoke callback. */ + cmd->cb(usc, cmd->data); + ring->queued--; + ring->next = (ring->next + 1) % ATHN_USB_HOST_CMD_RING_COUNT; + } +#endif +} + +// TODO? +void +athn_usb_do_async(struct athn_usb_softc *usc, + void (*cb)(struct athn_usb_softc *, void *), void *arg, int len) +{ +#if OpenBSD_ONLY + struct athn_usb_host_cmd_ring *ring = &usc->cmdq; + struct athn_usb_host_cmd *cmd; + int s; + + if (ring->queued == ATHN_USB_HOST_CMD_RING_COUNT) { + printf("%s: host cmd queue overrun\n", device_get_name(usc->usb_dev)); + return; /* XXX */ + } + + s = splusb(); + cmd = &ring->cmd[ring->cur]; + cmd->cb = cb; + KASSERT(len <= sizeof(cmd->data), "athn_usb_do_async"); + memcpy(cmd->data, arg, len); + ring->cur = (ring->cur + 1) % ATHN_USB_HOST_CMD_RING_COUNT; + + /* If there is no pending command already, schedule a task. */ + if (++ring->queued == 1) + usb_add_task(usc->sc_udev, &usc->sc_task); + splx(s); +#endif +} + +//TODO? +void +athn_usb_wait_async(struct athn_usb_softc *usc) +{ + /* Wait for all queued asynchronous commands to complete. */ +#if OpenBSD_ONLY + usb_wait_task(usc->sc_udev, &usc->sc_task); +#endif +} + +void +athn_usb_verify_fw(struct athn_usb_softc *usc) +{ + struct athn_softc *sc = &usc->sc_sc; + struct athn_usb_data *data; + + ATHN_LOCK(sc); + + data = STAILQ_FIRST(&usc->sc_cmd_inactive); + if (data == NULL) { + device_printf(sc->sc_dev, "%s: no tx cmd buffers\n", + __func__); + return; + } + STAILQ_REMOVE_HEAD(&usc->sc_cmd_inactive, next); +} + +int +athn_usb_htc_msg(struct athn_usb_softc *usc, uint16_t msg_id, void *buf, + int len) +{ + struct athn_softc *sc = &usc->sc_sc; + struct athn_usb_data *cmd; + struct ar_htc_frame_hdr *htc; + struct ar_htc_msg_hdr *msg; + int error = 0; + + device_printf(sc->sc_dev, "%s: message id: %d\n", __func__, msg_id); + + ATHN_ASSERT_LOCKED(sc); + + cmd = STAILQ_FIRST(&usc->sc_cmd_inactive); + if (cmd == NULL) { + device_printf(sc->sc_dev, "%s: no tx cmd buffers\n", + __func__); + return -1; + } + STAILQ_REMOVE_HEAD(&usc->sc_cmd_inactive, next); + + htc = (struct ar_htc_frame_hdr *)cmd->buf; + memset(htc, 0, sizeof(*htc)); + htc->endpoint_id = 0; + htc->payload_len = htobe16(sizeof(*msg) + len); + + msg = (struct ar_htc_msg_hdr *)&htc[1]; + msg->msg_id = htobe16(msg_id); + + memcpy(&msg[1], buf, len); + + cmd->buflen = sizeof(*htc) + sizeof(*msg) + len; + device_printf(sc->sc_dev, "%s: prepare transfer %p; buf=%p, buflen=%d\n", + __func__, cmd, cmd->buf, cmd->buflen); + + STAILQ_INSERT_TAIL(&usc->sc_cmd_pending, cmd, next); + usbd_transfer_start(usc->sc_xfer[ATHN_BULK_CMD]); + + return error; +} + +int +athn_usb_htc_setup(struct athn_usb_softc *usc) +{ + struct ar_htc_msg_config_pipe cfg; + int s, error; + + /* + * Connect WMI services to USB pipes. + */ + error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_CONTROL, + AR_PIPE_TX_INTR, AR_PIPE_RX_INTR, &usc->ep_ctrl); + if (error != 0) + return (error); + error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_BEACON, + AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_bcn); + if (error != 0) + return (error); + error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_CAB, + AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_cab); + if (error != 0) + return (error); + error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_UAPSD, + AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_uapsd); + if (error != 0) + return (error); + error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_MGMT, + AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_mgmt); + if (error != 0) + return (error); + error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_BE, + AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[ATHN_QID_AC_BE]); + if (error != 0) + return (error); + error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_BK, + AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[ATHN_QID_AC_BK]); + if (error != 0) + return (error); + error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_VI, + AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[ATHN_QID_AC_VI]); + if (error != 0) + return (error); + error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_VO, + AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[ATHN_QID_AC_VO]); + if (error != 0) + return (error); + + /* Set credits for WLAN Tx pipe. */ + memset(&cfg, 0, sizeof(cfg)); + cfg.pipe_id = UE_GET_ADDR(AR_PIPE_TX_DATA); + cfg.credits = (usc->flags & ATHN_USB_FLAG_AR7010) ? 45 : 33; + + ATHN_LOCK(&usc->sc_sc); + + usc->wait_msg_id = AR_HTC_MSG_CONF_PIPE_RSP; + error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONF_PIPE, &cfg, sizeof(cfg)); + if (error == 0 && usc->wait_msg_id != 0) + error = msleep(&usc->wait_msg_id, &usc->sc_sc.sc_mtx, PCATCH, "athnhtc", + hz); + usc->wait_msg_id = 0; + + ATHN_UNLOCK(&usc->sc_sc); + + if (error != 0) { + printf("%s: could not configure pipe\n", + device_get_name(usc->usb_dev)); + return (error); + } + + ATHN_LOCK(&usc->sc_sc); + + error = athn_usb_htc_msg(usc, AR_HTC_MSG_SETUP_COMPLETE, NULL, 0); + if (error != 0) { + ATHN_UNLOCK(&usc->sc_sc); + printf("%s: could not complete setup\n", + device_get_name(usc->usb_dev)); + return (error); + } + + ATHN_UNLOCK(&usc->sc_sc); + + return (0); +} + +int +athn_usb_htc_connect_svc(struct athn_usb_softc *usc, uint16_t svc_id, + uint8_t ul_pipe, uint8_t dl_pipe, uint8_t *endpoint_id) +{ + struct ar_htc_msg_conn_svc msg; + struct ar_htc_msg_conn_svc_rsp rsp; + int s, error; + + struct athn_softc *sc = &usc->sc_sc; + device_printf(sc->sc_dev, "%s: configuring svc_id %d \n", __func__, svc_id); + + memset(&msg, 0, sizeof(msg)); + msg.svc_id = htobe16(svc_id); + msg.dl_pipeid = UE_GET_ADDR(dl_pipe); + msg.ul_pipeid = UE_GET_ADDR(ul_pipe); + usc->msg_conn_svc_rsp = &rsp; + + ATHN_LOCK(&usc->sc_sc); + + usc->wait_msg_id = AR_HTC_MSG_CONN_SVC_RSP; + error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONN_SVC, &msg, sizeof(msg)); + /* Wait at most 1 second for response. */ + if (error == 0 && usc->wait_msg_id != 0) + error = msleep(&usc->wait_msg_id, &usc->sc_sc.sc_mtx, PCATCH, "athnhtc", hz * 2); + usc->wait_msg_id = 0; + + ATHN_UNLOCK(&usc->sc_sc); + + if (error != 0) { + device_printf(sc->sc_dev, "%s: error waiting for service %d connection " + "error: %d \n", __func__, htobe16(svc_id), error); + return (error); + } + if (rsp.status != AR_HTC_SVC_SUCCESS) { + device_printf(sc->sc_dev, "%s: service %d connection failed, " + "error: %d\n", __func__, htobe16(svc_id), rsp.status); + return (EIO); + } + + device_printf(sc->sc_dev, "%s: service %d successfully connected to endpoint %d\n", + __func__, svc_id, rsp.endpoint_id); + + /* Return endpoint id. */ + *endpoint_id = rsp.endpoint_id; + return (0); +} + +int +athn_usb_wmi_xcmd(struct athn_usb_softc *usc, uint16_t cmd_id, void *ibuf, + int ilen, void *obuf) +{ + struct athn_softc *sc = &usc->sc_sc; + struct athn_usb_data *data; + struct ar_htc_frame_hdr *htc; + struct ar_wmi_cmd_hdr *wmi; + int xferlen, error; + + // device_printf(sc->sc_dev, "%s: called \n", __func__); + + ATHN_ASSERT_LOCKED(sc); + + data = STAILQ_FIRST(&usc->sc_cmd_inactive); + if (data == NULL) { + device_printf(sc->sc_dev, "%s: no tx cmd buffers\n", + __func__); + return -1; + } + STAILQ_REMOVE_HEAD(&usc->sc_cmd_inactive, next); + + while (usc->wait_cmd_id) { + /* + * The previous USB transfer is not done yet. We can't use + * data->xfer until it is done or we'll cause major confusion + * in the USB stack. + */ + msleep(&usc->wait_msg_id, &usc->sc_sc.sc_mtx, PCATCH, "athnwmx", hz); + } + xferlen = sizeof(*htc) + sizeof(*wmi) + ilen; + data->buflen = xferlen; + + htc = (struct ar_htc_frame_hdr *)data->buf; + memset(htc, 0, sizeof(*htc)); + htc->endpoint_id = usc->ep_ctrl; + htc->payload_len = htobe16(sizeof(*wmi) + ilen); + + wmi = (struct ar_wmi_cmd_hdr *)&htc[1]; + wmi->cmd_id = htobe16(cmd_id); + usc->wmi_seq_no++; + wmi->seq_no = usc->wmi_seq_no; + usc->wait_msg_id = AR_WMI_CMD_MSG; + + memcpy(&wmi[1], ibuf, ilen); + + usc->wait_cmd_id = cmd_id; + usc->obuf = obuf; + STAILQ_INSERT_TAIL(&usc->sc_cmd_pending, data, next); + usbd_transfer_start(usc->sc_xfer[ATHN_BULK_CMD]); + + /* + * Wait for WMI command complete interrupt. In case it does not fire + * wait until the USB transfer times out to avoid racing the transfer. + */ + error = msleep(&usc->wait_cmd_id, &usc->sc_sc.sc_mtx, PCATCH, "athnwmi", 2*hz); + if (error == EWOULDBLOCK) { + printf("%s: firmware command 0x%x timed out\n", + device_get_name(usc->usb_dev), cmd_id); + error = ETIMEDOUT; + } + + device_printf(sc->sc_dev, "%s: aftersleep\n", __func__); + + /* + * Both the WMI command and transfer are done or have timed out. + * Allow other threads to enter this function and use data->xfer. + */ + usc->obuf = NULL; + usc->wait_msg_id = 0; + usc->wait_cmd_id = 0; + wakeup(&usc->wait_cmd_id); + + return (error); +} + +int +athn_usb_read_rom(struct athn_softc *sc) +{ + struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; + uint32_t addrs[8], vals[8], addr; + uint16_t *eep; + int i, j, error; + + /* Read EEPROM by blocks of 16 bytes. */ + eep = sc->eep; + addr = AR_EEPROM_OFFSET(sc->eep_base); + for (i = 0; i < sc->eep_size / 16; i++) { + DELAY(3000); + for (j = 0; j < 8; j++, addr += 4) + addrs[j] = htobe32(addr); + error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_READ, + addrs, sizeof(addrs), vals); + DELAY(3000); + if (error != 0) + { + printf("error in reading rom\n"); + break; + } + for (j = 0; j < 8; j++) + *eep++ = betoh32(vals[j]); + } + return (error); +} + +uint32_t +athn_usb_read(struct athn_softc *sc, uint32_t addr) +{ + struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; + uint32_t val; + int error; + + device_printf(sc->sc_dev, "%s: called \n", __func__); + + /* Flush pending writes for strict consistency. */ + athn_usb_write_barrier(sc); + + addr = htobe32(addr); + error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_READ, + &addr, sizeof(addr), &val); + if (error != 0) + device_printf(sc->sc_dev, + "%s: error \n", + __func__); + return betoh32(val); +} + +void +athn_usb_write(struct athn_softc *sc, uint32_t addr, uint32_t val) +{ + struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; + + usc->wbuf[usc->wcount].addr = htobe32(addr); + usc->wbuf[usc->wcount].val = htobe32(val); + if (++usc->wcount == AR_MAX_WRITE_COUNT) + athn_usb_write_barrier(sc); +} + +void +athn_usb_write_barrier(struct athn_softc *sc) +{ + struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; + + if (usc->wcount == 0) + return; /* Nothing to write. */ + + (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_WRITE, + usc->wbuf, usc->wcount * sizeof(usc->wbuf[0]), NULL); + usc->wcount = 0; /* Always flush buffer. */ +} + +int +athn_usb_media_change(struct ifnet *ifp) +{ + struct athn_usb_softc *usc = (struct athn_usb_softc *)ifp->if_softc; + int error; + + error = ieee80211_media_change(ifp); + if (error != ENETRESET) + return (error); + + if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == + (IFF_UP | IFF_RUNNING)) { + athn_usb_stop(ifp); + error = athn_usb_init(ifp); + } + + return (error); +} + +// TODO +void +athn_usb_next_scan(void *arg, int pending) +{ + struct athn_usb_softc *usc = arg; + struct athn_softc *sc = &usc->sc_sc; + struct ieee80211com *ic = &sc->sc_ic; + int s; + +#if OpenBSD_IEEE80211_API + if (ic->ic_state == IEEE80211_S_SCAN) + ieee80211_next_scan(&ic->ic_if); +#endif +} + +// uncomment after investigation if it is needed to be async +// int +// athn_usb_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, +// int arg) +// { +// struct ieee80211com *ic = vap->iv_ic; +// struct athn_usb_softc *usc = ic->ic_softc; +// struct athn_vap *uvp = ATHN_VAP(vap); +// struct athn_usb_cmd_newstate cmd; + +// /* Do it in a process context. */ +// cmd.state = nstate; +// cmd.arg = arg; +// athn_usb_do_async(usc, athn_usb_newstate_cb, &cmd, sizeof(cmd)); +// return (0); +// } + +// TODO +int +athn_usb_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, + int arg) +{ + struct athn_vap *uvp = ATHN_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; + struct athn_usb_softc *usc = ic->ic_softc; + struct athn_softc *sc = &usc->sc_sc; + struct ieee80211_node *ni = ieee80211_ref_node(vap->iv_bss); + enum ieee80211_state ostate; + uint32_t reg, imask; + int s, error; +#if OpenBSD_ONLY + timeout_del(&sc->calib_to); +#endif + IEEE80211_UNLOCK(ic); + ATHN_LOCK(sc); + ostate = vap->iv_state; + + if (ostate == IEEE80211_S_RUN && ic->ic_opmode == IEEE80211_M_STA) { + athn_usb_remove_node(usc, ni); + reg = AR_READ(sc, AR_RX_FILTER); + reg = (reg & ~AR_RX_FILTER_MYBEACON) | + AR_RX_FILTER_BEACON; + AR_WRITE(sc, AR_RX_FILTER, reg); + AR_WRITE_BARRIER(sc); + } + + switch (nstate) { + case IEEE80211_S_INIT: + athn_set_led(sc, 0); + break; + case IEEE80211_S_SCAN: + /* Make the LED blink while scanning. */ + // athn_set_led(sc, !sc->led_state); + // error = athn_usb_switch_chan(sc, ni->ni_chan, NULL); + // if (error) + // printf("%s: could not switch to channel %d\n", + // device_get_name(usc->usb_dev), 0); + // ieee80211_chan2ieee(ic, ni->ni_chan); + // // uncomment after investigation if it is needed to be async + // // if (!usbd_is_dying(usc->sc_udev)) + // // timeout_add_msec(&sc->scan_to, 200); + break; + case IEEE80211_S_AUTH: + athn_set_led(sc, 0); + error = athn_usb_switch_chan(sc, ni->ni_chan, NULL); + if (error) + printf("%s: could not switch to channel %d\n", + device_get_name(usc->usb_dev), 0); + ieee80211_chan2ieee(ic, ni->ni_chan); + break; + case IEEE80211_S_ASSOC: + break; + case IEEE80211_S_RUN: + athn_set_led(sc, 1); + + if (ic->ic_opmode == IEEE80211_M_MONITOR) + break; + + if (ic->ic_opmode == IEEE80211_M_STA) { + /* Create node entry for our BSS */ + error = athn_usb_create_node(usc, ni); + if (error) + printf("%s: could not update firmware station " + "table\n", device_get_name(usc->usb_dev)); + } + athn_set_bss(sc, ni); + athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR); +#ifndef IEEE80211_STA_ONLY + if (ic->ic_opmode == IEEE80211_M_HOSTAP) { + athn_usb_switch_chan(sc, ni->ni_chan, NULL); + athn_set_hostap_timers(sc); + /* Enable software beacon alert interrupts. */ + imask = htobe32(AR_IMR_SWBA); + } else +#endif + { + athn_set_sta_timers(sc); + /* Enable beacon miss interrupts. */ + imask = htobe32(AR_IMR_BMISS); + + /* Stop receiving beacons from other BSS. */ + reg = AR_READ(sc, AR_RX_FILTER); + reg = (reg & ~AR_RX_FILTER_BEACON) | + AR_RX_FILTER_MYBEACON; + AR_WRITE(sc, AR_RX_FILTER, reg); + AR_WRITE_BARRIER(sc); + } + athn_usb_wmi_xcmd(usc, AR_WMI_CMD_ENABLE_INTR, + &imask, sizeof(imask), NULL); + break; + default: + break; + } +#if OpenBSD_IEEE80211_API + return sc->sc_newstate(ic, state, arg); + splx(s); + #endif + ATHN_UNLOCK(sc); + IEEE80211_LOCK(ic); + return (uvp->newstate(vap, nstate, arg)); +} + +// TODO +void +athn_usb_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, + int isnew) +{ +#ifndef IEEE80211_STA_ONLY + struct athn_usb_softc *usc = ic->ic_softc; +#if OpenBSD_IEEE80211_API + if (ic->ic_opmode != IEEE80211_M_HOSTAP && + ic->ic_state != IEEE80211_S_RUN) + return; +#endif + /* Update the node's supported rates in a process context. */ + ieee80211_ref_node(ni); + athn_usb_do_async(usc, athn_usb_newassoc_cb, &ni, sizeof(ni)); +#endif +} + +#ifndef IEEE80211_STA_ONLY +// TODO +void +athn_usb_newassoc_cb(struct athn_usb_softc *usc, void *arg) +{ + struct ieee80211com *ic = &usc->sc_sc.sc_ic; + struct ieee80211_node *ni = *(void **)arg; + struct athn_node *an = (struct athn_node *)ni; + int s; +#if OpenBSD_IEEE80211_API + if (ic->ic_state != IEEE80211_S_RUN) + return; + + s = splnet(); + /* NB: Node may have left before we got scheduled. */ + if (an->sta_index != 0) + (void)athn_usb_node_set_rates(usc, ni); + ieee80211_release_node(ic, ni); + splx(s); +#endif +} +#endif + +struct ieee80211_node * +athn_usb_node_alloc(struct ieee80211com *ic) +{ + struct athn_node *an; + + an = malloc(sizeof(struct athn_node), M_USBDEV, M_NOWAIT | M_ZERO); + return (struct ieee80211_node *)an; +} + + +#ifndef IEEE80211_STA_ONLY +void +athn_usb_count_active_sta(void *arg, struct ieee80211_node *ni) +{ + int *nsta = arg; + struct athn_node *an = (struct athn_node *)ni; + + if (an->sta_index == 0) + return; +#if OpenBSD_IEEE80211_API + if ((ni->ni_state == IEEE80211_STA_AUTH || + ni->ni_state == IEEE80211_STA_ASSOC) && + ni->ni_inact < IEEE80211_INACT_MAX) + (*nsta)++; +#endif +} + +struct athn_usb_newauth_cb_arg { + struct ieee80211_node *ni; + uint16_t seq; +}; + + +//TODO: Not sure if needed +void +athn_usb_newauth_cb(struct athn_usb_softc *usc, void *arg) +{ + struct ieee80211com *ic = &usc->sc_sc.sc_ic; + struct athn_usb_newauth_cb_arg *a = arg; + struct ieee80211_node *ni = a->ni; + uint16_t seq = a->seq; + struct athn_node *an = (struct athn_node *)ni; + int s, error = 0; + +#if OpenBSD_IEEE80211_API + if (ic->ic_state != IEEE80211_S_RUN) + return; +#endif + + s = splnet(); + if (an->sta_index == 0) { + error = athn_usb_create_node(usc, ni); + if (error) + printf("%s: could not add station %s to firmware " + "table\n", device_get_name(usc->usb_dev), + ether_sprintf(ni->ni_macaddr)); + } +#if OpenBSD_IEEE80211_API + if (error == 0) + ieee80211_auth_open_confirm(ic, ni, seq); + ieee80211_unref_node(&ni); +#endif + splx(s); +} +#endif + +// TODO: not sure if needed +int +athn_usb_newauth(struct ieee80211com *ic, struct ieee80211_node *ni, + int isnew, uint16_t seq) +{ +#ifndef IEEE80211_STA_ONLY + struct athn_usb_softc *usc = ic->ic_softc; +#if OpenBSD_IEEE80211_API + struct ifnet *ifp = &ic->ic_if; +#endif + struct athn_node *an = (struct athn_node *)ni; + int nsta; + struct athn_usb_newauth_cb_arg arg; + + if (ic->ic_opmode != IEEE80211_M_HOSTAP) + return 0; + + if (!isnew && an->sta_index != 0) /* already in firmware table */ + return 0; + + /* Check if we have room in the firmware table. */ + nsta = 1; /* Account for default node. */ +#if OpenBSD_IEEE80211_API + ieee80211_iterate_nodes(ic, athn_usb_count_active_sta, &nsta); + if (nsta >= AR_USB_MAX_STA) { + if (ifp->if_flags & IFF_DEBUG) + printf("%s: cannot authenticate station %s: firmware " + "table is full\n", device_get_name(usc->usb_dev), + ether_sprintf(ni->ni_macaddr)); + return ENOSPC; + } +#endif + + /* + * In a process context, try to add this node to the + * firmware table and confirm the AUTH request. + */ + arg.ni = ieee80211_ref_node(ni); + arg.seq = seq; + athn_usb_do_async(usc, athn_usb_newauth_cb, &arg, sizeof(arg)); + return EBUSY; +#else + return 0; +#endif /* IEEE80211_STA_ONLY */ +} + +#ifndef IEEE80211_STA_ONLY +void +athn_usb_node_free(struct ieee80211com *ic, struct ieee80211_node *ni) +{ + struct athn_usb_softc *usc = ic->ic_softc; + struct athn_node *an = (struct athn_node *)ni; + + /* + * Remove the node from the firmware table in a process context. + * Pass an index rather than the pointer which we will free. + */ + if (an->sta_index != 0) + athn_usb_do_async(usc, athn_usb_node_free_cb, + &an->sta_index, sizeof(an->sta_index)); + usc->sc_node_free(ic, ni); +} + +void +athn_usb_node_free_cb(struct athn_usb_softc *usc, void *arg) +{ + struct ieee80211com *ic = &usc->sc_sc.sc_ic; +#if OpenBSD_IEEE80211_API + struct ifnet *ifp = &ic->ic_if; +#endif + uint8_t sta_index = *(uint8_t *)arg; + int error; + + error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE, + &sta_index, sizeof(sta_index), NULL); + if (error) { + printf("%s: could not remove station %u from firmware table\n", + device_get_name(usc->usb_dev), sta_index); + return; + } + usc->free_node_slots |= (1 << sta_index); +#if OpenBSD_IEEE80211_API + if (ifp->if_flags & IFF_DEBUG) + printf("%s: station %u removed from firmware table\n", + device_get_name(usc->usb_dev), sta_index); +#endif +} +#endif /* IEEE80211_STA_ONLY */ + +int +athn_usb_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni, + uint8_t tid) +{ + struct athn_usb_softc *usc = ic->ic_softc; + struct athn_node *an = (struct athn_node *)ni; + struct athn_usb_aggr_cmd cmd; + + /* Do it in a process context. */ + cmd.sta_index = an->sta_index; + cmd.tid = tid; + // athn_usb_do_async(usc, athn_usb_ampdu_tx_start_cb, &cmd, sizeof(cmd)); + + athn_usb_ampdu_tx_start_cb(usc, &cmd); + return (0); +} + +void +athn_usb_ampdu_tx_start_cb(struct athn_usb_softc *usc, void *arg) +{ + struct athn_usb_aggr_cmd *cmd = arg; + struct ar_htc_target_aggr aggr; + + memset(&aggr, 0, sizeof(aggr)); + aggr.sta_index = cmd->sta_index; + aggr.tidno = cmd->tid; + aggr.aggr_enable = 1; + (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TX_AGGR_ENABLE, + &aggr, sizeof(aggr), NULL); +} + +void +athn_usb_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni, + uint8_t tid) +{ + struct athn_usb_softc *usc = ic->ic_softc; + struct athn_node *an = (struct athn_node *)ni; + struct athn_usb_aggr_cmd cmd; + + /* Do it in a process context. */ + cmd.sta_index = an->sta_index; + cmd.tid = tid; + athn_usb_do_async(usc, athn_usb_ampdu_tx_stop_cb, &cmd, sizeof(cmd)); +} + +void +athn_usb_ampdu_tx_stop_cb(struct athn_usb_softc *usc, void *arg) +{ + struct athn_usb_aggr_cmd *cmd = arg; + struct ar_htc_target_aggr aggr; + + memset(&aggr, 0, sizeof(aggr)); + aggr.sta_index = cmd->sta_index; + aggr.tidno = cmd->tid; + aggr.aggr_enable = 0; + (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TX_AGGR_ENABLE, + &aggr, sizeof(aggr), NULL); +} + +#ifndef IEEE80211_STA_ONLY +/* Try to find a node we can evict to make room in the firmware table. */ +// TODO +void +athn_usb_clean_nodes(void *arg, struct ieee80211_node *ni) +{ + struct athn_usb_softc *usc = arg; + struct ieee80211com *ic = &usc->sc_sc.sc_ic; + struct athn_node *an = (struct athn_node *)ni; + + /* + * Don't remove the default node (used for management frames). + * Nodes which are not in the firmware table also have index zero. + */ + if (an->sta_index == 0) + return; + +#if OpenBSD_IEEE80211_API + /* Remove non-associated nodes. */ + if (ni->ni_state != IEEE80211_STA_AUTH && + ni->ni_state != IEEE80211_STA_ASSOC) { + athn_usb_remove_node(usc, ni); + return; + } + + /* + * Kick off inactive associated nodes. This won't help + * immediately but will help if the new STA retries later. + */ + if (ni->ni_inact >= IEEE80211_INACT_MAX) { + IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, + IEEE80211_REASON_AUTH_EXPIRE); + ieee80211_node_leave(ic, ni); + } +#endif +} +#endif + +int +athn_usb_create_node(struct athn_usb_softc *usc, struct ieee80211_node *ni) +{ + struct athn_node *an = (struct athn_node *)ni; + struct ar_htc_target_sta sta; + int error, sta_index; +#ifndef IEEE80211_STA_ONLY + struct ieee80211com *ic = &usc->sc_sc.sc_ic; +#if OpenBSD_IEEE80211_API + struct ifnet *ifp = &ic->ic_if; +#endif + + /* Firmware cannot handle more than 8 STAs. Try to make room first. */ +#if OpenBSD_IEEE80211_API + if (ic->ic_opmode == IEEE80211_M_HOSTAP) + ieee80211_iterate_nodes(ic, athn_usb_clean_nodes, usc); +#endif +#endif + if (usc->free_node_slots == 0x00) + return ENOBUFS; + + sta_index = ffs(usc->free_node_slots) - 1; + if (sta_index < 0 || sta_index >= AR_USB_MAX_STA) + return ENOSPC; + + /* Create node entry on target. */ + memset(&sta, 0, sizeof(sta)); + IEEE80211_ADDR_COPY(sta.macaddr, ni->ni_macaddr); + IEEE80211_ADDR_COPY(sta.bssid, ni->ni_bssid); + sta.sta_index = sta_index; + sta.maxampdu = 0xffff; + if (ni->ni_flags & IEEE80211_NODE_HT) + sta.flags |= htobe16(AR_HTC_STA_HT); + error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_CREATE, + &sta, sizeof(sta), NULL); + if (error != 0) + return (error); + an->sta_index = sta_index; + usc->free_node_slots &= ~(1 << an->sta_index); + +#if OpenBSD_IEEE80211_API +#ifndef IEEE80211_STA_ONLY + if (ifp->if_flags & IFF_DEBUG) + printf("%s: station %u (%s) added to firmware table\n", + device_get_name(usc->usb_dev), sta_index, + ether_sprintf(ni->ni_macaddr)); +#endif +#endif + return athn_usb_node_set_rates(usc, ni); +} + +// TODO +int +athn_usb_node_set_rates(struct athn_usb_softc *usc, struct ieee80211_node *ni) +{ + struct athn_node *an = (struct athn_node *)ni; + struct ar_htc_target_rate rate; + int i, j; + + /* Setup supported rates. */ + memset(&rate, 0, sizeof(rate)); + rate.sta_index = an->sta_index; + rate.isnew = 1; + rate.lg_rates.rs_nrates = ni->ni_rates.rs_nrates; + memcpy(rate.lg_rates.rs_rates, ni->ni_rates.rs_rates, + ni->ni_rates.rs_nrates); + if (ni->ni_flags & IEEE80211_NODE_HT) { + rate.capflags |= htobe32(AR_RC_HT_FLAG); + /* Setup HT rates. */ + #if OpenBSD_IEEE80211_API + for (i = 0, j = 0; i < IEEE80211_HT_NUM_MCS; i++) { + if (!isset(ni->ni_rxmcs, i)) + continue; + if (j >= AR_HTC_RATE_MAX) + break; + rate.ht_rates.rs_rates[j++] = i; + } + #endif + rate.ht_rates.rs_nrates = j; + +#if OpenBSD_IEEE80211_API + if (ni->ni_rxmcs[1]) /* dual-stream MIMO rates */ + rate.capflags |= htobe32(AR_RC_DS_FLAG); +#endif +#ifdef notyet + if (ni->ni_htcaps & IEEE80211_HTCAP_CBW20_40) + rate.capflags |= htobe32(AR_RC_40_FLAG); + if (ni->ni_htcaps & IEEE80211_HTCAP_SGI40) + rate.capflags |= htobe32(AR_RC_SGI_FLAG); + if (ni->ni_htcaps & IEEE80211_HTCAP_SGI20) + rate.capflags |= htobe32(AR_RC_SGI_FLAG); +#endif + } + + return athn_usb_wmi_xcmd(usc, AR_WMI_CMD_RC_RATE_UPDATE, + &rate, sizeof(rate), NULL); +} + +int +athn_usb_remove_node(struct athn_usb_softc *usc, struct ieee80211_node *ni) +{ + struct athn_node *an = (struct athn_node *)ni; + int error; +#ifndef IEEE80211_STA_ONLY + struct ieee80211com *ic = &usc->sc_sc.sc_ic; +#if OpenBSD_IEEE80211_API + struct ifnet *ifp = &ic->ic_if; +#endif +#endif + + error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE, + &an->sta_index, sizeof(an->sta_index), NULL); + if (error) { + printf("%s: could not remove station %u (%s) from " + "firmware table\n", device_get_name(usc->usb_dev), an->sta_index, + ether_sprintf(ni->ni_macaddr)); + return error; + } +#if OpenBSD_IEEE80211_API +#ifndef IEEE80211_STA_ONLY + if (ifp->if_flags & IFF_DEBUG) + printf("%s: station %u (%s) removed from firmware table\n", + device_get_name(usc->usb_dev), an->sta_index, + ether_sprintf(ni->ni_macaddr)); +#endif +#endif + usc->free_node_slots |= (1 << an->sta_index); + an->sta_index = 0; + return 0; +} + +void +athn_usb_rx_enable(struct athn_softc *sc) +{ + AR_WRITE(sc, AR_CR, AR_CR_RXE); + AR_WRITE_BARRIER(sc); +} + +//TODO +int +athn_usb_switch_chan(struct athn_softc *sc, struct ieee80211_channel *c, + struct ieee80211_channel *extc) +{ + struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; + uint16_t mode; + int error; + + /* Disable interrupts. */ + error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR); + if (error != 0) + goto reset; + /* Stop all Tx queues. */ + error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_DRAIN_TXQ_ALL); + if (error != 0) + goto reset; + /* Stop Rx. */ + error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_STOP_RECV); + if (error != 0) + goto reset; + + // TODO + // /* If band or bandwidth changes, we need to do a full reset. */ + // if (c->ic_flags != sc->curchan->ic_flags || + // ((extc != NULL) ^ (sc->curchanext != NULL))) { + // DPRINTFN(2, ("channel band switch\n")); + // goto reset; + // } + + error = athn_set_chan(sc, c, extc); + if (AR_SREV_9271(sc) && error == 0) + ar9271_load_ani(sc); + if (error != 0) { + reset: /* Error found, try a full reset. */ + DPRINTFN(3, ("needs a full reset\n")); + error = athn_hw_reset(sc, c, extc, 0); + if (error != 0) /* Hopeless case. */ + return (error); + + error = athn_set_chan(sc, c, extc); + if (AR_SREV_9271(sc) && error == 0) + ar9271_load_ani(sc); + if (error != 0) + return (error); + } + + sc->ops.set_txpower(sc, c, extc); + + error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV); + if (error != 0) + return (error); + athn_rx_start(sc); + + mode = htobe16(IEEE80211_IS_CHAN_2GHZ(c) ? + AR_HTC_MODE_11NG : AR_HTC_MODE_11NA); + error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_SET_MODE, + &mode, sizeof(mode), NULL); + if (error != 0) + return (error); + + /* Re-enable interrupts. */ + error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_ENABLE_INTR); + return (error); +} + +// TODO? +void +athn_usb_updateedca(struct ieee80211com *ic) +{ + struct athn_usb_softc *usc = ic->ic_softc; + + /* Do it in a process context. */ + athn_usb_do_async(usc, athn_usb_updateedca_cb, NULL, 0); +} + +// TODO? Not sure if needed +void +athn_usb_updateedca_cb(struct athn_usb_softc *usc, void *arg) +{ + int s; + + s = splnet(); + athn_updateedca(&usc->sc_sc.sc_ic); + splx(s); +} + +// TODO? Not sure if needed +void +athn_usb_updateslot(struct ieee80211com *ic) +{ + struct athn_usb_softc *usc = ic->ic_softc; + + return; /* XXX */ + /* Do it in a process context. */ + athn_usb_do_async(usc, athn_usb_updateslot_cb, NULL, 0); +} + +// TODO? Not sure if needed +void +athn_usb_updateslot_cb(struct athn_usb_softc *usc, void *arg) +{ + int s; + + s = splnet(); + athn_updateslot(&usc->sc_sc.sc_ic); + splx(s); +} + +// TODO? Not sure if needed +int +athn_usb_set_key(struct ieee80211com *ic, struct ieee80211_node *ni, + struct ieee80211_key *k) +{ + struct athn_usb_softc *usc = ic->ic_softc; + struct athn_usb_cmd_key cmd; + + /* Defer setting of WEP keys until interface is brought up. */ +#if OpenBSD_IEEE80211_API + if ((ic->ic_if.if_flags & (IFF_UP | IFF_RUNNING)) != + (IFF_UP | IFF_RUNNING)) + return (0); +#endif + + /* Do it in a process context. */ + cmd.ni = (ni != NULL) ? ieee80211_ref_node(ni) : NULL; + cmd.key = k; + athn_usb_do_async(usc, athn_usb_set_key_cb, &cmd, sizeof(cmd)); + usc->sc_key_tasks++; + return EBUSY; +} + +// TODO? Not sure if needed +void +athn_usb_set_key_cb(struct athn_usb_softc *usc, void *arg) +{ + struct ieee80211com *ic = &usc->sc_sc.sc_ic; + struct athn_usb_cmd_key *cmd = arg; + int s; + + usc->sc_key_tasks--; + + s = splnet(); + athn_usb_write_barrier(&usc->sc_sc); + athn_set_key(ic, cmd->ni, cmd->key); +#if OpenBSD_IEEE80211_API + if (usc->sc_key_tasks == 0) { + DPRINTF(("marking port %s valid\n", + ether_sprintf(cmd->ni->ni_macaddr))); + cmd->ni->ni_port_valid = 1; + ieee80211_set_link_state(ic, LINK_STATE_UP); + } + if (cmd->ni != NULL) + ieee80211_release_node(ic, cmd->ni); + splx(s); +#endif +} + +// TODO? Not sure if needed +void +athn_usb_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, + struct ieee80211_key *k) +{ + struct athn_usb_softc *usc = ic->ic_softc; + struct athn_usb_cmd_key cmd; +#if OpenBSD_IEEE80211_API + if (!(ic->ic_if.if_flags & IFF_RUNNING) || + ic->ic_state != IEEE80211_S_RUN) + return; /* Nothing to do. */ +#endif + /* Do it in a process context. */ + cmd.ni = (ni != NULL) ? ieee80211_ref_node(ni) : NULL; + cmd.key = k; + athn_usb_do_async(usc, athn_usb_delete_key_cb, &cmd, sizeof(cmd)); +} + +// TODO? Not sure if needed +void +athn_usb_delete_key_cb(struct athn_usb_softc *usc, void *arg) +{ + struct ieee80211com *ic = &usc->sc_sc.sc_ic; + struct athn_usb_cmd_key *cmd = arg; + int s; + + s = splnet(); + athn_delete_key(ic, cmd->ni, cmd->key); +#if OpenBSD_IEEE80211_API + if (cmd->ni != NULL) + ieee80211_release_node(ic, cmd->ni); + splx(s); +#endif +} + +#ifndef IEEE80211_STA_ONLY +// TODO +void +athn_usb_bcneof(struct usb_xfer *xfer, void *priv, + usb_error_t status) +{ + struct athn_usb_data *data = priv; +#if OpenBSD_ONLY + struct athn_usb_softc *usc = data->sc; + + if (__predict_false(status == USB_ERR_STALLED)) + usbd_clear_endpoint_stall_async(usc->tx_data_pipe); + usc->tx_bcn = data; +#endif +} + + +// TODO +/* + * Process Software Beacon Alert interrupts. + */ +void +athn_usb_swba(struct athn_usb_softc *usc) +{ + struct athn_softc *sc = &usc->sc_sc; + struct ieee80211com *ic = &sc->sc_ic; + struct athn_usb_data *data; + struct ieee80211_frame *wh; + struct ar_stream_hdr *hdr; + struct ar_htc_frame_hdr *htc; + struct ar_tx_bcn *bcn; + struct mbuf *m; + int error; +#if OpenBSD_IEEE80211_API + if (ic->ic_dtim_count == 0) + ic->ic_dtim_count = ic->ic_dtim_period - 1; + else + ic->ic_dtim_count--; +#endif +#if OpenBSD_ONLY + /* Make sure previous beacon has been sent. */ + if (usc->tx_bcn == NULL) + return; + data = usc->tx_bcn; +#endif +#if OpenBSD_IEEE80211_API + /* Get new beacon. */ + m = ieee80211_beacon_alloc(ic, ic->ic_bss); + if (__predict_false(m == NULL)) + return; + /* Assign sequence number. */ + wh = mtod(m, struct ieee80211_frame *); + *(uint16_t *)&wh->i_seq[0] = + htole16(ic->ic_bss->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT); + ic->ic_bss->ni_txseq++; + + hdr = (struct ar_stream_hdr *)data->buf; + hdr->tag = htole16(AR_USB_TX_STREAM_TAG); + hdr->len = htole16(sizeof(*htc) + sizeof(*bcn) + m->m_pkthdr.len); + + htc = (struct ar_htc_frame_hdr *)&hdr[1]; + memset(htc, 0, sizeof(*htc)); + htc->endpoint_id = usc->ep_bcn; + htc->payload_len = htobe16(sizeof(*bcn) + m->m_pkthdr.len); + + bcn = (struct ar_tx_bcn *)&htc[1]; + memset(bcn, 0, sizeof(*bcn)); + bcn->vif_idx = 0; + + m_copydata(m, 0, m->m_pkthdr.len, &bcn[1]); +#endif +#if OpenBSD_ONLY + usbd_setup_xfer(data->xfer, usc->tx_data_pipe, data, data->buf, + sizeof(*hdr) + sizeof(*htc) + sizeof(*bcn) + m->m_pkthdr.len, + USBD_SHORT_XFER_OK | USBD_NO_COPY, ATHN_USB_TX_TIMEOUT, + athn_usb_bcneof); + + m_freem(m); + usc->tx_bcn = NULL; + error = usbd_transfer_start(data->xfer); + if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) + usc->tx_bcn = data; +#endif +} +#endif + +// TODO +/* Update current transmit rate for a node based on firmware Tx status. */ +void +athn_usb_tx_status(void *arg, struct ieee80211_node *ni) +{ + struct ar_wmi_evt_txstatus *ts = arg; + struct athn_node *an = (struct athn_node *)ni; + uint8_t rate_index = (ts->rate & AR_HTC_TXSTAT_RATE); + + if (an->sta_index != ts->cookie) /* Tx report for a different node */ + return; +#if OpenBSD_IEEE80211_API + if (ts->flags & AR_HTC_TXSTAT_MCS) { + if (isset(ni->ni_rxmcs, rate_index)) + ni->ni_txmcs = rate_index; + } else if (rate_index < ni->ni_rates.rs_nrates) + ni->ni_txrate = rate_index; +#endif +} + +void +athn_usb_rx_wmi_ctrl(struct athn_usb_softc *usc, uint8_t *buf, int len) +{ + struct ar_wmi_cmd_hdr *wmi; + uint16_t cmd_id; + + if (__predict_false(len < sizeof(*wmi))) + return; + wmi = (struct ar_wmi_cmd_hdr *)buf; + cmd_id = betoh16(wmi->cmd_id); + + if (!(cmd_id & AR_WMI_EVT_FLAG)) { + if (usc->wait_cmd_id != cmd_id) + return; /* Unexpected reply. */ + if (usc->obuf != NULL) { + /* Copy answer into caller supplied buffer. */ + memcpy(usc->obuf, &wmi[1], len - sizeof(*wmi)); + } + /* Notify caller of completion. */ + wakeup(&usc->wait_cmd_id); + return; + } + switch (cmd_id & 0xfff) { +#ifndef IEEE80211_STA_ONLY + case AR_WMI_EVT_SWBA: + athn_usb_swba(usc); + break; +#endif + case AR_WMI_EVT_TXSTATUS: { + struct ar_wmi_evt_txstatus_list *tsl; + int i; + + tsl = (struct ar_wmi_evt_txstatus_list *)&wmi[1]; + for (i = 0; i < tsl->count && i < nitems(tsl->ts); i++) { + struct ieee80211com *ic = &usc->sc_sc.sc_ic; +#if OpenBSD_IEEE80211_API + struct athn_node *an = (struct athn_node *)ic->ic_bss; +#endif + struct ar_wmi_evt_txstatus *ts = &tsl->ts[i]; + uint8_t qid; + + /* Skip the node we use to send management frames. */ + if (ts->cookie == 0) + continue; + + /* Skip Tx reports for non-data frame endpoints. */ + qid = (ts->rate & AR_HTC_TXSTAT_EPID) >> + AR_HTC_TXSTAT_EPID_SHIFT; + if (qid != usc->ep_data[ATHN_QID_AC_BE] && + qid != usc->ep_data[ATHN_QID_AC_BK-1] && + qid != usc->ep_data[ATHN_QID_AC_VI-1] && + qid != usc->ep_data[ATHN_QID_AC_VO-1]) + continue; +#if OpenBSD_IEEE80211_API + if (ts->cookie == an->sta_index) + athn_usb_tx_status(ts, ic->ic_bss); + else + ieee80211_iterate_nodes(ic, athn_usb_tx_status, + ts); +#endif + } + break; + } + case AR_WMI_EVT_FATAL: + printf("%s: fatal firmware error\n", device_get_name(usc->usb_dev)); + break; + default: + DPRINTF(("WMI event %d ignored\n", cmd_id)); + break; + } +} + +#if NBPFILTER > 0 + +// TODO? +void +athn_usb_rx_radiotap(struct athn_softc *sc, struct mbuf *m, + struct ar_rx_status *rs) +{ +#define IEEE80211_RADIOTAP_F_SHORTGI 0x80 /* XXX from FBSD */ + + struct athn_rx_radiotap_header *tap = &sc->sc_rxtap; + struct ieee80211com *ic = &sc->sc_ic; + struct mbuf mb; + uint8_t rate; + + tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; + tap->wr_tsft = htole64(betoh64(rs->rs_tstamp)); + tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq); + tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags); + tap->wr_dbm_antsignal = rs->rs_rssi; + /* XXX noise. */ + tap->wr_antenna = rs->rs_antenna; + tap->wr_rate = 0; /* In case it can't be found below. */ + rate = rs->rs_rate; + if (rate & 0x80) { /* HT. */ + /* Bit 7 set means HT MCS instead of rate. */ + tap->wr_rate = rate; + if (!(rs->rs_flags & AR_RXS_FLAG_GI)) + tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI; + + } else if (rate & 0x10) { /* CCK. */ + if (rate & 0x04) + tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; + switch (rate & ~0x14) { + case 0xb: tap->wr_rate = 2; break; + case 0xa: tap->wr_rate = 4; break; + case 0x9: tap->wr_rate = 11; break; + case 0x8: tap->wr_rate = 22; break; + } + } else { /* OFDM. */ + switch (rate) { + case 0xb: tap->wr_rate = 12; break; + case 0xf: tap->wr_rate = 18; break; + case 0xa: tap->wr_rate = 24; break; + case 0xe: tap->wr_rate = 36; break; + case 0x9: tap->wr_rate = 48; break; + case 0xd: tap->wr_rate = 72; break; + case 0x8: tap->wr_rate = 96; break; + case 0xc: tap->wr_rate = 108; break; + } + } + mb.m_data = (caddr_t)tap; + mb.m_len = sc->sc_rxtap_len; + mb.m_next = m; + mb.m_nextpkt = NULL; + mb.m_type = 0; + mb.m_flags = 0; + bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN); +} +#endif + +// TODO +void +athn_usb_rx_frame(struct athn_usb_softc *usc, struct mbuf *m/*, + struct mbuf_list *ml*/) +{ +#if OpenBSD_ONLY + struct athn_softc *sc = &usc->sc_sc; + struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = &ic->ic_if; + struct ieee80211_frame *wh; + struct ieee80211_node *ni; + struct ieee80211_rxinfo rxi; + + struct ar_htc_frame_hdr *htc; + struct ar_rx_status *rs; + uint16_t datalen; + int s; + + if (__predict_false(m->m_len < sizeof(*htc))) + goto skip; + htc = mtod(m, struct ar_htc_frame_hdr *); + if (__predict_false(htc->endpoint_id == 0)) { + DPRINTF(("bad endpoint %d\n", htc->endpoint_id)); + goto skip; + } + if (htc->flags & AR_HTC_FLAG_TRAILER) { + if (m->m_len < htc->control[0]) + goto skip; + m_adj(m, -(int)htc->control[0]); + } + m_adj(m, sizeof(*htc)); /* Strip HTC header. */ + + if (__predict_false(m->m_len < sizeof(*rs))) + goto skip; + rs = mtod(m, struct ar_rx_status *); + + /* Make sure that payload fits. */ + datalen = betoh16(rs->rs_datalen); + if (__predict_false(m->m_len < sizeof(*rs) + datalen)) + goto skip; + + if (__predict_false(datalen < sizeof(*wh) + IEEE80211_CRC_LEN)) + goto skip; + + if (rs->rs_status != 0) { + if (rs->rs_status & AR_RXS_RXERR_DECRYPT) + ic->ic_stats.is_ccmp_dec_errs++; + goto skip; + } + + m_adj(m, sizeof(*rs)); /* Strip Rx status. */ + + s = splnet(); + + /* Grab a reference to the source node. */ + + wh = mtod(m, struct ieee80211_frame *); + ni = ieee80211_find_rxnode(ic, wh); + + /* Remove any HW padding after the 802.11 header. */ + if (!(wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL)) { + + u_int hdrlen = ieee80211_get_hdrlen(wh); + if (hdrlen & 3) { + memmove((caddr_t)wh + 2, wh, hdrlen); + m_adj(m, 2); + } + wh = mtod(m, struct ieee80211_frame *); + } + +#if NBPFILTER > 0 + if (__predict_false(sc->sc_drvbpf != NULL)) + athn_usb_rx_radiotap(sc, m, rs); +#endif + /* Trim 802.11 FCS after radiotap. */ + m_adj(m, -IEEE80211_CRC_LEN); + + /* Send the frame to the 802.11 layer. */ + + memset(&rxi, 0, sizeof(rxi)); + rxi.rxi_rssi = rs->rs_rssi + AR_USB_DEFAULT_NF; + rxi.rxi_tstamp = betoh64(rs->rs_tstamp); + + if (!(wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL) && + (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) && + (ic->ic_flags & IEEE80211_F_RSNON) && + (ni->ni_flags & IEEE80211_NODE_RXPROT) && + (ni->ni_rsncipher == IEEE80211_CIPHER_CCMP || + (IEEE80211_IS_MULTICAST(wh->i_addr1) && + ni->ni_rsngroupcipher == IEEE80211_CIPHER_CCMP))) { + if (ar5008_ccmp_decap(sc, m, ni) != 0) { + ieee80211_release_node(ic, ni); + splx(s); + goto skip; + } + rxi.rxi_flags |= IEEE80211_RXI_HWDEC; + } + ieee80211_inputm(ifp, m, ni, &rxi, ml); + + + /* Node is no longer needed. */ + ieee80211_release_node(ic, ni); + + splx(s); + return; + skip: + m_freem(m); +#endif +} + +// TODO +void +athn_usb_rxeof(struct usb_xfer *xfer, struct athn_usb_data *data) +{ +#if OpenBSD_ONLY + struct mbuf_list ml = MBUF_LIST_INITIALIZER(); +#endif + struct athn_usb_softc *usc = usbd_xfer_softc(xfer); +#if OpenBSD_IEEE80211_API + struct ifnet *ifp = &sc->sc_ic.ic_if; +#endif + struct athn_usb_rx_stream *stream = &usc->rx_stream; + char *buf = data->buf; + struct ar_stream_hdr *hdr; + struct mbuf *m; + uint16_t pktlen; + int off; + int32_t len; + +#if OpenBSD_ONLY + if (__predict_false(status != USBD_NORMAL_COMPLETION)) { + DPRINTF(("RX status=%d\n", status)); + if (status == USBD_STALLED) + usbd_clear_endpoint_stall_async(usc->rx_data_pipe); + if (status != USBD_CANCELLED) + goto resubmit; + return; + } +#endif + usbd_xfer_status(xfer, NULL, NULL, &len, NULL); + + if (stream->left > 0) { + if (len >= stream->left) { + /* We have all our pktlen bytes now. */ + if (__predict_true(stream->m != NULL)) { + memcpy(mtod(stream->m, uint8_t *) + + stream->moff, buf, stream->left); + athn_usb_rx_frame(usc, stream->m/*, &ml*/); // MichalP: mbuf_list doesn't exist in FreeBSD + stream->m = NULL; + } + /* Next header is 32-bit aligned. */ + off = (stream->left + 3) & ~3; + buf += off; + len -= off; + stream->left = 0; + } else { + /* Still need more bytes, save what we have. */ + if (__predict_true(stream->m != NULL)) { + memcpy(mtod(stream->m, uint8_t *) + + stream->moff, buf, len); + stream->moff += len; + } + stream->left -= len; + goto resubmit; + } + } + KASSERT(stream->left == 0, "athn_usb_rxeof"); + while (len >= sizeof(*hdr)) { + hdr = (struct ar_stream_hdr *)buf; + if (hdr->tag != htole16(AR_USB_RX_STREAM_TAG)) { + DPRINTF(("invalid tag 0x%x\n", hdr->tag)); + break; + } + pktlen = letoh16(hdr->len); + buf += sizeof(*hdr); + len -= sizeof(*hdr); +#if OpenBSD_ONLY // MichalP: mbuf_list operations needs proper refactoring + if (__predict_true(pktlen <= MCLBYTES)) { + /* Allocate an mbuf to store the next pktlen bytes. */ + MGETHDR(m, M_DONTWAIT, MT_DATA); + if (__predict_true(m != NULL)) { + m->m_pkthdr.len = m->m_len = pktlen; + if (pktlen > MHLEN) { + MCLGET(m, M_DONTWAIT); + if (!(m->m_flags & M_EXT)) { + m_free(m); + m = NULL; + } + } + } + } else /* Drop frames larger than MCLBYTES. */ + m = NULL; +#endif + /* + * NB: m can be NULL, in which case the next pktlen bytes + * will be discarded from the Rx stream. + */ + if (pktlen > len) { + /* Need more bytes, save what we have. */ + stream->m = m; /* NB: m can be NULL. */ + if (__predict_true(stream->m != NULL)) { + memcpy(mtod(stream->m, uint8_t *), buf, len); + stream->moff = len; + } + stream->left = pktlen - len; + goto resubmit; + } + if (__predict_true(m != NULL)) { + /* We have all the pktlen bytes in this xfer. */ + memcpy(mtod(m, uint8_t *), buf, pktlen); + athn_usb_rx_frame(usc, m/*, &ml*/); // MichalP: Another mbuf_list + } + + /* Next header is 32-bit aligned. */ + off = (pktlen + 3) & ~3; + buf += off; + len -= off; + } +#if OpenBSD_IEEE80211_API + // TODO Refactor functions which use mbuf_list. + // mbuf_list is OpenBSD specific and if_input uses the mbuf directly. + // In the next steps, we should remove mbuf_list support from this driver. + if_input(ifp, m); +#endif + + resubmit: + printf("Resubmit called"); // MichalP: Temp printf call to maintain resubmit goto + /* Setup a new transfer. */ +#if OpenBSD_ONLY + usbd_setup_xfer(xfer, usc->rx_data_pipe, data, data->buf, + ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, + USBD_NO_TIMEOUT, athn_usb_rxeof); + (void)usbd_transfer_start(xfer); +#endif +} + +// TODO: needs improvement +void +athn_usb_txeof(struct usb_xfer *xfer, struct athn_usb_data* data) +{ + struct athn_usb_softc *usc = usbd_xfer_softc(xfer); + struct athn_softc *sc = &usc->sc_sc; +#if OpenBSD_IEEE80211_API + struct ifnet *ifp = &sc->sc_ic.ic_if; +#endif + + // device_printf(sc->sc_dev, "%s: called; data=%p\n", __func__, data); + + ATHN_ASSERT_LOCKED(sc); + + if (usc->sc_tx_n_active == 0) { + device_printf(sc->sc_dev, + "%s: completed but tx_active=0\n", + __func__); + } else { + usc->sc_tx_n_active--; + } + + // if (data->m) { + // /* XXX status? */ + // /* XXX we get TX status via the RX path.. */ + // ieee80211_tx_complete(data->ni, data->m, 0); + // data->m = NULL; + // data->ni = NULL; + // } +} + +// TODO: needs improvement +int +athn_usb_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, struct athn_usb_data *data, const struct ieee80211_bpf_params *params) +{ + struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; + struct athn_node *an = (struct athn_node *)ni; + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_frame *wh; + struct ieee80211_key *k = NULL; + struct ar_stream_hdr *hdr; + struct ar_htc_frame_hdr *htc; + struct ar_tx_frame *txf; + struct ar_tx_mgmt *txm; + uint8_t *frm; + uint16_t qos; + uint8_t qid, tid = 0; + int hasqos, xferlen, error; + + wh = mtod(m, struct ieee80211_frame *); + if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { + // TODO: consider 'ieee80211_crypto_get_txkey' instead of 'ieee80211_crypto_encap' + // for proper if-else + k = ieee80211_crypto_encap(ni, m); + if (k == NULL) { + device_printf(sc->sc_dev, + "%s: m=%p: ieee80211_crypto_encap returns NULL\n", + __func__, + m); + return (ENOBUFS); + } +// TODO: encryption - see the 'cipher' variable in 'rtwn_tx_data' function and 'rtwn_get_cipher' +#if OpenBSD_ONLY + else if (k->k_cipher == IEEE80211_CIPHER_CCMP) { + u_int hdrlen = ieee80211_get_hdrlen(wh); + if (ar5008_ccmp_encap(m, hdrlen, k) != 0) + return (ENOBUFS); + } +#else + else { + device_printf(sc->sc_dev, + "%s:CIPHER_CCMP not ported\n", __func__ ); + return (ENOTSUP); + } +#endif + wh = mtod(m, struct ieee80211_frame *); + } + + hasqos = !! IEEE80211_QOS_HAS_SEQ(wh); + + if (hasqos) { + uint8_t tid; + qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0]; + tid = qos & IEEE80211_QOS_TID; + qid = TID_TO_WME_AC(tid); + } else { + qos = 0; + qid = WME_AC_BE; + } + +// OpenBSD code +#if 0 + /* Grab a Tx buffer from our free list. */ + data = TAILQ_FIRST(&usc->tx_free_list); + TAILQ_REMOVE(&usc->tx_free_list, data, next); +// Based on otus +#else + // Not needed, data passed as a function parameter with athn_getbuf +#endif + + +#if NBPFILTER > 0 + /* XXX Change radiotap Tx header for USB (no txrate). */ + if (__predict_false(sc->sc_drvbpf != NULL)) { + struct athn_tx_radiotap_header *tap = &sc->sc_txtap; + struct mbuf mb; + + tap->wt_flags = 0; + tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq); + tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags); + mb.m_data = (caddr_t)tap; + mb.m_len = sc->sc_txtap_len; + mb.m_next = m; + mb.m_nextpkt = NULL; + mb.m_type = 0; + mb.m_flags = 0; + bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT); + } +#endif + + /* NB: We don't take advantage of USB Tx stream mode for now. */ + hdr = (struct ar_stream_hdr *)data->buf; + hdr->tag = htole16(AR_USB_TX_STREAM_TAG); + + htc = (struct ar_htc_frame_hdr *)&hdr[1]; + memset(htc, 0, sizeof(*htc)); + if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == + IEEE80211_FC0_TYPE_DATA) { + htc->endpoint_id = usc->ep_data[qid]; + + txf = (struct ar_tx_frame *)&htc[1]; + memset(txf, 0, sizeof(*txf)); + txf->data_type = AR_HTC_NORMAL; + txf->node_idx = an->sta_index; + txf->vif_idx = 0; + txf->tid = tid; + if (m->m_pkthdr.len + IEEE80211_CRC_LEN >= vap->iv_rtsthreshold) + txf->flags |= htobe32(AR_HTC_TX_RTSCTS); + else if (ic->ic_flags & IEEE80211_F_USEPROT) { + if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) + txf->flags |= htobe32(AR_HTC_TX_CTSONLY); + else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) + txf->flags |= htobe32(AR_HTC_TX_RTSCTS); + } + + if (k != NULL) { +#if OpenBSD_ONLY + /* Map 802.11 cipher to hardware encryption type. */ + if (k->k_cipher == IEEE80211_CIPHER_CCMP) { + txf->key_type = AR_ENCR_TYPE_AES; + } else + panic("unsupported cipher"); + + /* + * NB: The key cache entry index is stored in the key + * private field when the key is installed. + */ + txf->key_idx = (uintptr_t)k->k_priv; +#else + device_printf(sc->sc_dev, + "%s:CIPHER_CCMP not ported\n", __func__ ); + txf->key_idx = 0xff; + #endif + } else + txf->key_idx = 0xff; + + txf->cookie = an->sta_index; + frm = (uint8_t *)&txf[1]; + } else { + htc->endpoint_id = usc->ep_mgmt; + + txm = (struct ar_tx_mgmt *)&htc[1]; + memset(txm, 0, sizeof(*txm)); + txm->node_idx = an->sta_index; + txm->vif_idx = 0; + txm->key_idx = 0xff; + txm->cookie = an->sta_index; + frm = (uint8_t *)&txm[1]; + } + /* Copy payload. */ + m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)frm); + frm += m->m_pkthdr.len; + // TODO: In otus OpenBSD this line is present but isn't present in FreeBSD otus + // m_freem(m); + + /* Finalize headers. */ + htc->payload_len = htobe16(frm - (uint8_t *)&htc[1]); + hdr->len = htole16(frm - (uint8_t *)&hdr[1]); + xferlen = frm - (uint8_t *)data->buf; + + // TODO: 3 lines below copied from otus FreeBSD + data->buflen = xferlen; + data->ni = ni; + data->m = m; + + device_printf(sc->sc_dev, + "%s:BULK transfer start of data=%p; ni_txrate=%d\n", + __func__, data, (int) ni->ni_txrate); + + STAILQ_INSERT_TAIL(&usc->sc_tx_pending[ATHN_BULK_TX], data, next); + usbd_transfer_start(usc->sc_xfer[ATHN_BULK_TX]); + + return (0); +} + +void +athn_usb_start(struct ifnet *ifp) +{ + struct athn_softc *sc = ifp->if_softc; + struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_node *ni; + struct mbuf *m; + + if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive()) + return; + + for (;;) { +#if OpenBSD_ONLY + if (TAILQ_EMPTY(&usc->tx_free_list)) { + ifq_set_oactive(); + break; + } +#endif + /* Send pending management frames first. */ +#if OpenBSD_IEEE80211_API + m = mq_dequeue(&ic->ic_mgtq); + if (m != NULL) { + ni = m->m_pkthdr.ph_cookie; + goto sendit; + } + if (ic->ic_state != IEEE80211_S_RUN) + break; +#endif + + /* Encapsulate and send data frames. */ + ALTQ_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; +#if NBPFILTER > 0 + f (ifp->if_bpf != NULL) + bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); +#endif +#if OpenBSD_IEEE80211_API + if ((m = ieee80211_encap(ifp, m, &ni)) == NULL) + continue; +#endif + sendit: +#if NBPFILTER > 0 + if (ic->ic_rawbpf != NULL) + bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT); +#endif +// if (athn_usb_tx(sc, m, ni) != 0) { +// #if OpenBSD_IEEE80211_API +// ieee80211_release_node(ic, ni); +// #endif +// continue; +// } + + sc->sc_tx_timer = 5; + } +} + +void +athn_usb_watchdog(struct ifnet *ifp) +{ + struct athn_softc *sc = ifp->if_softc; + + if (sc->sc_tx_timer > 0) { + if (--sc->sc_tx_timer == 0) { + printf("%s: device timeout\n", device_get_name(sc->sc_dev)); + athn_usb_init(ifp); + return; + } + } +#if OpenBSD_IEEE80211_API + ieee80211_watchdog(ifp); +#endif +} + +int +athn_usb_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +{ + struct athn_softc *sc = ifp->if_softc; + struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; + struct ieee80211com *ic = &sc->sc_ic; + int s, error = 0; + + switch (cmd) { + case SIOCSIFADDR: + ifp->if_flags |= IFF_UP; + /* FALLTHROUGH */ + case SIOCSIFFLAGS: + if (ifp->if_flags & IFF_UP) { + if (!(ifp->if_flags & IFF_RUNNING)) + error = athn_usb_init(ifp); + } else { + if (ifp->if_flags & IFF_RUNNING) + athn_usb_stop(ifp); + } + break; +#if OpenBSD_IEEE80211_API + case SIOCS80211CHANNEL: + error = ieee80211_ioctl(ifp, cmd, data); + if (error == ENETRESET && + ic->ic_opmode == IEEE80211_M_MONITOR) { + if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == + (IFF_UP | IFF_RUNNING)) { + athn_usb_switch_chan(sc, ic->ic_ibss_chan, + NULL); + } + error = 0; + } + break; +#endif + default: + error = ieee80211_ioctl(ifp, cmd, data); + } + + if (error == ENETRESET) { + error = 0; + if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == + (IFF_UP | IFF_RUNNING)) { + athn_usb_stop(ifp); + error = athn_usb_init(ifp); + } + } + return (error); +} + +int +athn_usb_init(struct ifnet *ifp) +{ + struct athn_softc *sc = ifp->if_softc; + struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; + struct athn_ops *ops = &sc->ops; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_channel *c, *extc; + struct athn_usb_data *data; + struct ar_htc_target_vif hvif; + struct ar_htc_target_sta sta; + struct ar_htc_cap_target hic; + uint16_t mode; + int i, error; + +#if OpenBSD_IEEE80211_API + c = ic->ic_bss->ni_chan = ic->ic_ibss_chan; + extc = NULL; + + /* In case a new MAC address has been configured. */ + IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); +#endif + ATHN_LOCK(sc); + error = athn_set_power_awake(sc); + ATHN_UNLOCK(sc); + if (error != 0) + goto fail; + + error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_FLUSH_RECV); + if (error != 0) + goto fail; + + error = athn_hw_reset(sc, c, extc, 1); + if (error != 0) + goto fail; + + ops->set_txpower(sc, c, extc); + + mode = htobe16(IEEE80211_IS_CHAN_2GHZ(c) ? + AR_HTC_MODE_11NG : AR_HTC_MODE_11NA); + error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_SET_MODE, + &mode, sizeof(mode), NULL); + if (error != 0) + goto fail; + + error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_ATH_INIT); + if (error != 0) + goto fail; + + error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV); + if (error != 0) + goto fail; + + athn_rx_start(sc); + + /* Create main interface on target. */ + memset(&hvif, 0, sizeof(hvif)); + hvif.index = 0; +#if OpenBSD_IEEE80211_API + IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_myaddr); +#endif + switch (ic->ic_opmode) { + case IEEE80211_M_STA: + hvif.opmode = htobe32(AR_HTC_M_STA); + break; + case IEEE80211_M_MONITOR: + hvif.opmode = htobe32(AR_HTC_M_MONITOR); + break; +#ifndef IEEE80211_STA_ONLY + case IEEE80211_M_IBSS: + hvif.opmode = htobe32(AR_HTC_M_IBSS); + break; + case IEEE80211_M_AHDEMO: + hvif.opmode = htobe32(AR_HTC_M_AHDEMO); + break; + case IEEE80211_M_HOSTAP: + hvif.opmode = htobe32(AR_HTC_M_HOSTAP); + break; + case IEEE80211_M_MBSS: + break; + case IEEE80211_M_WDS: + break; +#endif + } +// #if OpenBSD_IEEE80211_API + // hvif.rtsthreshold = htobe16(ic->ic_rtsthreshold); +// #endif + DPRINTF(("creating VAP\n")); + error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_VAP_CREATE, + &hvif, sizeof(hvif), NULL); + if (error != 0) + goto fail; + + /* Create a fake node to send management frames before assoc. */ + memset(&sta, 0, sizeof(sta)); +#if OpenBSD_IEEE80211_API + IEEE80211_ADDR_COPY(sta.macaddr, ic->ic_myaddr); +#endif + sta.sta_index = 0; + sta.is_vif_sta = 1; + sta.vif_index = hvif.index; + sta.maxampdu = 0xffff; + DPRINTF(("creating default node\n")); + error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_CREATE, + &sta, sizeof(sta), NULL); + if (error != 0) + goto fail; + usc->free_node_slots = ~(1 << sta.sta_index); + + /* Update target capabilities. */ + memset(&hic, 0, sizeof(hic)); + hic.ampdu_limit = htobe32(0x0000ffff); + hic.ampdu_subframes = 20; + hic.txchainmask = sc->txchainmask; + DPRINTF(("updating target configuration\n")); + error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TARGET_IC_UPDATE, + &hic, sizeof(hic), NULL); + if (error != 0) + goto fail; + +// TODO +#if OpenBSD_ONLY + /* Queue Rx xfers. */ + for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) { + data = &usc->rx_data[i]; + usbd_setup_xfer(data->xfer, usc->rx_data_pipe, data, data->buf, + ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, + USBD_NO_TIMEOUT, athn_usb_rxeof); + error = usbd_transfer_start(data->xfer); + if (error != 0 && error != USBD_IN_PROGRESS) + goto fail; + } +#endif + /* We're ready to go. */ + ifp->if_flags |= IFF_RUNNING; + ifq_clr_oactive(); + +#ifdef notyet + if (ic->ic_flags & IEEE80211_F_WEPON) { + /* Install WEP keys. */ + for (i = 0; i < IEEE80211_WEP_NKID; i++) + athn_usb_set_key(ic, NULL, &ic->ic_nw_keys[i]); + } +#endif +#if OpenBSD_IEEE80211_API + if (ic->ic_opmode == IEEE80211_M_MONITOR) + ieee80211_new_state(ic, IEEE80211_S_RUN, -1); + else + ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); +#endif + athn_usb_wait_async(usc); + return (0); + fail: + athn_usb_stop(ifp); + return (error); +} + +void +athn_usb_stop(struct ifnet *ifp) +{ + struct athn_softc *sc = ifp->if_softc; + struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; + struct ieee80211com *ic = &sc->sc_ic; + struct ar_htc_target_vif hvif; + uint8_t sta_index; + int s; + + sc->sc_tx_timer = 0; + ifp->if_flags &= ~IFF_RUNNING; + ifq_clr_oactive(); + + s = splusb(); +#if OpenBSD_IEEE80211_API + ieee80211_new_state(ic, IEEE80211_S_INIT, -1); +#endif + + /* Wait for all async commands to complete. */ + athn_usb_wait_async(usc); + +#if OpenBSD_ONLY + timeout_del(&sc->scan_to); + timeout_del(&sc->calib_to); +#endif + + /* Remove all non-default nodes. */ + for (sta_index = 1; sta_index < AR_USB_MAX_STA; sta_index++) { + if (usc->free_node_slots & (1 << sta_index)) + continue; + (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE, + &sta_index, sizeof(sta_index), NULL); + } + + /* Remove main interface. This also invalidates our default node. */ + memset(&hvif, 0, sizeof(hvif)); + hvif.index = 0; +#if OpenBSD_IEEE80211_API + IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_myaddr); +#endif + (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_VAP_REMOVE, + &hvif, sizeof(hvif), NULL); + + usc->free_node_slots = 0xff; + + (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR); + (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_DRAIN_TXQ_ALL); + (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_STOP_RECV); + + ATHN_LOCK(sc); + athn_reset(sc, 0); + athn_init_pll(sc, NULL); + athn_set_power_awake(sc); + athn_reset(sc, 1); + athn_init_pll(sc, NULL); + ATHN_UNLOCK(sc); + + athn_set_power_sleep(sc); + + +#if OpenBSD_ONLY + /* Abort Tx/Rx. */ + usbd_abort_pipe(usc->tx_data_pipe); + usbd_abort_pipe(usc->rx_data_pipe); +#endif + + /* Free Tx/Rx buffers. */ + athn_usb_free_tx_list(usc); + athn_usb_free_rx_list(usc); + splx(s); + + /* Flush Rx stream. */ + m_freem(usc->rx_stream.m); + usc->rx_stream.m = NULL; + usc->rx_stream.left = 0; +} diff --git a/sys/dev/athn/if_athn_usb_fw.c b/sys/dev/athn/if_athn_usb_fw.c new file mode 100644 --- /dev/null +++ b/sys/dev/athn/if_athn_usb_fw.c @@ -0,0 +1,173 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "athnreg.h" +#include "ar5008reg.h" +#include "athnvar.h" + + +// FreeBSD version +#include +#include + +#include "if_athn_usb.h" + +static const struct firmware *fware = NULL; + +extern int tsleep_nsec(const void *ident, int priority, const char *wmesg, uint64_t nsecs); + +void +athn_usb_unload_firmware() +{ + if (fware == NULL) { + printf("Fail: null firmware handler\n"); + return; + } + + firmware_put(fware, FIRMWARE_UNLOAD); + printf("Successully called firmware_put\n"); + return; +} + +int +athn_usb_get_firmware(struct athn_usb_softc *usc, struct ar_wmi_fw_version *version) +{ + usb_device_descriptor_t *dd; + const char *name; + int error = ENXIO; + + /* Determine which firmware image to load. */ + if (usc->flags & ATHN_USB_FLAG_AR7010) { + dd = usbd_get_device_descriptor(usc->sc_udev); + name = "athn-open-ar7010.bin"; + } else + name = "athn-open-ar9271.bin"; + /* Read firmware image from the filesystem. */ + fware = firmware_get(name); + if (fware == NULL) { + printf("Failed firmware_get of file %s\n", name); + return (error); + } else { + printf("Success firmware_get of file %s\n", name); + printf("Firmware name: %s:\n", fware->name); + printf("Firmware version: %u:\n", fware->version); + printf("Firmware size: %zu:\n", fware->datasize); + version->major = fware->version / 100; + version->minor = (fware->version / 10) % 10; + return 0; + } +} + +int +athn_usb_transfer_firmware(struct athn_usb_softc *usc) +{ + usb_device_request_t req; + const char *name; + void *ptr; + size_t fwsize, size; + uint32_t addr; + int s, mlen; + int error = 0; + + ATHN_LOCK(&usc->sc_sc); + +/* Load firmware image. */ + ptr = (void *)fware->data; + addr = AR9271_FIRMWARE >> 8; + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = AR_FW_DOWNLOAD; + USETW(req.wIndex, 0); + size = fware->datasize; + + while (size > 0) { + printf("Uploading %zu bytes\n", size); + mlen = MIN(size, 4096); + + USETW(req.wValue, addr); + USETW(req.wLength, mlen); + + error = usbd_do_request(usc->sc_udev, &usc->sc_sc.sc_mtx, &req, ptr); + if (error != 0) { + ATHN_UNLOCK(&usc->sc_sc); + athn_usb_unload_firmware(); + return (error); + } + addr += mlen >> 8; + ptr += mlen; + size -= mlen; + } + + /* Start firmware. */ + if (usc->flags & ATHN_USB_FLAG_AR7010) + addr = AR7010_FIRMWARE_TEXT >> 8; + else { + addr = AR9271_FIRMWARE_TEXT >> 8; + device_printf(usc->sc_sc.sc_dev, "%s: selected device: AR9271\n", __func__); + } + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = AR_FW_DOWNLOAD_COMP; + USETW(req.wIndex, 0); + USETW(req.wValue, addr); + USETW(req.wLength, 0); + + usc->wait_msg_id = AR_HTC_MSG_READY; + error = usbd_do_request(usc->sc_udev, &usc->sc_sc.sc_mtx, &req, NULL); + + /* Wait at most 1 second for firmware to boot. */ + device_printf(usc->sc_sc.sc_dev, "%s: Waiting for firmware to boot\n", __func__); + if (error == 0 && usc->wait_msg_id != 0) + error = msleep(&usc->wait_msg_id, &usc->sc_sc.sc_mtx, PCATCH, "athnfw", hz); + + if (usc->wait_msg_id == 0) { + device_printf(usc->sc_sc.sc_dev, "%s: Firmware booted successfully!\n", __func__); + } + + ATHN_UNLOCK(&usc->sc_sc); + + athn_usb_unload_firmware(); + + return (error); +} + +int +athn_usb_load_firmware(struct athn_usb_softc *usc, struct ar_wmi_fw_version *img_version) +{ + int error = 0; + + error = athn_usb_get_firmware(usc, img_version); + if (error) { + printf("Failed to get firmware\n"); + return error; + } + + error = athn_usb_transfer_firmware(usc); + if (error) { + printf("Failed to transfer firmware to the device\n"); + } + + return error; +} \ No newline at end of file diff --git a/sys/modules/usb/athn/Makefile b/sys/modules/usb/athn/Makefile new file mode 100644 --- /dev/null +++ b/sys/modules/usb/athn/Makefile @@ -0,0 +1,38 @@ +# $FreeBSD$ + +INCDIR=${SRCTOP}/sys/compat/linuxkpi/common/include + +.PATH: ${SRCTOP}/sys/dev/usb/wlan ${SRCTOP}/sys/dev/athn + +.include + +KMOD = if_athn + +EXPORT_SYMS= YES + +#SRCS= if_athn_usb.c ar9285.c athn.c +SRCS= if_athn_usb_fw.c if_athn_usb.c athn_stubs.c athn.c +SRCS+= ar9285.c ar9280.c ar5008.c +SRCS+= bus_if.h device_if.h +SRCS+= opt_inet.h opt_inet6.h opt_route.h opt_netlink.h + +SRCS+= ${LINUXKPI_GENSRCS} + +CFLAGS+= -ferror-limit=0 +# CFLAGS+= ${LINUXKPI_INCLUDES} +CFLAGS+= -I${INCDIR} +CFLAGS+= -I${SRCTOP}/sys/dev/athn/headers +# CFLAGS+= -I${SRCTOP}/sys/compat/linuxkpi/dummy/include/openbsd + +DEBUG_FLAGS+= -O0 -g + +# CFLAGS+= -I${SRCTOP}/sys/dev/athn/include/amd64 +# CFLAGS+= -I${SRCTOP}/sys/dev/athn/include/sys +# CFLAGS+= -I${SRCTOP}/sys/dev/athn/include/net80211 + + +CWARNFLAGS+= ${NO_WUNUSED_BUT_SET_VARIABLE} +CWARNFLAGS+= ${NO_WUNUSED_PARAMETER} +CWARNFLAGS+= ${NO_WUNUSED_FUNCTION} + +.include diff --git a/sys/modules/usb/athnfw/Makefile b/sys/modules/usb/athnfw/Makefile new file mode 100644 --- /dev/null +++ b/sys/modules/usb/athnfw/Makefile @@ -0,0 +1,10 @@ +IMG= athn-open-ar9271.bin + +KMOD= ${IMG} +CLEANFILES+= ${IMG} +FIRMWS= ${IMG}:${IMG}:141 + +${IMG}: ${SRCTOP}/sys/contrib/dev/athnfw/${IMG} + cp ${.ALLSRC} ${.TARGET} + +.include \ No newline at end of file