Page MenuHomeFreeBSD

D45821.diff
No OneTemporary

D45821.diff

This file is larger than 256 KB, so syntax highlighting was skipped.
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$@<O00001
literal 0
Hc$@<O00001
diff --git a/sys/contrib/dev/athnfw/athn-open-ar9271.bin.lnx b/sys/contrib/dev/athnfw/athn-open-ar9271.bin.lnx
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
literal 0
Hc$@<O00001
diff --git a/sys/dev/athn/ar5008.c b/sys/dev/athn/ar5008.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/ar5008.c
@@ -0,0 +1,3114 @@
+/* $OpenBSD: ar5008.c,v 1.71 2022/12/27 20:13:03 patrick Exp $ */
+
+/*-
+ * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
+ * 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 <sys/param.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+// #include <sys/timeout.h>
+#include <sys/conf.h>
+// #include <sys/device.h>
+#include <sys/stdint.h> /* uintptr_t */
+#include <sys/endian.h>
+
+#include <machine/bus.h>
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <net/ethernet.h>
+
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_radiotap.h>
+#include <net80211/ieee80211_ratectl.h>
+
+#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 <damien.bergamini@free.fr>
+ * 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 <sys/param.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+// #include <sys/timeout.h>
+#include <sys/conf.h>
+// #include <sys/device.h>
+#include <sys/endian.h>
+
+#include <machine/bus.h>
+// #include <machine/intr.h>
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_radiotap.h>
+#include <net80211/ieee80211_ratectl.h>
+
+#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 <damien.bergamini@free.fr>
+ * 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 <sys/param.h>
+#include <sys/sockio.h>
+// #include <openbsd/openbsd_mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+//#include <sys/timeout.h>
+#include <sys/conf.h>
+//#include <sys/device.h>
+#include <sys/endian.h>
+
+#include <machine/bus.h>
+//#include <machine/intr.h>
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_arp.h>
+
+#include <netinet/in.h>
+//#include <netinet/if_ether.h>
+#include <net/ethernet.h>
+
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_radiotap.h>
+#include <net80211/ieee80211_ratectl.h>
+
+#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 <damien.bergamini@free.fr>
+ * 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 <sys/param.h>
+#include <sys/sockio.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/conf.h>
+#include <sys/stdint.h> /* uintptr_t */
+#include <sys/endian.h>
+#include <machine/bus.h>
+
+// #if NBPFILTER > 0
+// #include <net/bpf.h>
+// #endif
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_regdomain.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#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 <sys/param.h>
+#include <sys/sockio.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/conf.h>
+#include <sys/stdint.h> /* uintptr_t */
+#include <sys/endian.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#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 <damien.bergamini@free.fr>
+ * 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 <damien.bergamini@free.fr>
+ * 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 <damien.bergamini@free.fr>
+ * 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 <damien.bergamini@free.fr>
+ * 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 <damien.bergamini@free.fr>
+ * 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 <damien.bergamini@free.fr>
+ *
+ * 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 <openbsd/openbsd_queue.h>
+#include <sys/bus.h>
+#include <sys/bus_dma.h>
+#include "../../../../crypto/openssh/openbsd-compat/sys-queue.h"
+#include "openbsd_adapt.h"
+//#include <openbsd_device.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
+#include <sys/taskqueue.h>
+#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 <damien.bergamini@free.fr>
+ * Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
+ *
+ * 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 <sys/endian.h>
+// 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 <damien.bergamini@free.fr>
+ * Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
+ *
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/limits.h>
+#include <sys/mutex.h>
+#include <sys/module.h>
+#include <sys/firmware.h>
+#include <sys/sockio.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+#include <sys/kdb.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_radiotap.h>
+#include <net80211/ieee80211_ratectl.h>
+
+#include "athnreg.h"
+#include "ar5008reg.h"
+#include "athnvar.h"
+
+#include <openbsd/openbsd_usbdevs.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usb_device.h>
+//#include <dev/usb/usb_core.h>
+#include <dev/usb/usbdi_util.h>
+
+#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 <sys/types.h>
+#include <sys/param.h>
+#include <sys/module.h>
+#include <sys/firmware.h>
+#include <sys/sockio.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/endian.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+
+#include <net/if_var.h>
+
+#include <net/if_arp.h>
+#include <netinet/in.h>
+
+#include <net/ethernet.h>
+#include <net80211/ieee80211_freebsd.h>
+#include <net80211/ieee80211_power.h>
+#include <net80211/ieee80211_node.h>
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_radiotap.h>
+#include <openbsd_adapt.h>
+
+#include "athnreg.h"
+#include "ar5008reg.h"
+#include "athnvar.h"
+
+
+// FreeBSD version
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#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 <src.opts.mk>
+
+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 <bsd.kmod.mk>
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 <bsd.kmod.mk>
\ No newline at end of file

File Metadata

Mime Type
text/plain
Expires
Sat, Feb 7, 12:46 AM (13 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28451775
Default Alt Text
D45821.diff (834 KB)

Event Timeline