Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- *** ../oldral/if_ral_pci.c Thu May 19 17:16:46 2011
- --- if_ral_pci.c Mon Jun 6 17:26:55 2011
- ***************
- *** 1,10 ****
- --- 1,11 ----
- /* $FreeBSD: src/sys/dev/ral/if_ral_pci.c,v 1.9 2009/03/09 13:23:54 imp Exp $ */
- /*-
- * Copyright (c) 2005, 2006
- * Damien Bergamini <[email protected]>
- + * Minor changes for rt2860 and bugs added by Matt ([email protected])
- *
- * 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.
- *
- ***************
- *** 19,29 ****
- #include <sys/cdefs.h>
- __FBSDID("$FreeBSD: src/sys/dev/ral/if_ral_pci.c,v 1.9 2009/03/09 13:23:54 imp Exp $");
- /*
- ! * PCI/Cardbus front-end for the Ralink RT2560/RT2561/RT2561S/RT2661 driver.
- */
- #include <sys/param.h>
- #include <sys/sysctl.h>
- #include <sys/sockio.h>
- --- 20,30 ----
- #include <sys/cdefs.h>
- __FBSDID("$FreeBSD: src/sys/dev/ral/if_ral_pci.c,v 1.9 2009/03/09 13:23:54 imp Exp $");
- /*
- ! * PCI/Cardbus front-end for the Ralink RT2560/RT2561/RT2561S/RT2661/RT2860/RT3090 driver.
- */
- #include <sys/param.h>
- #include <sys/sysctl.h>
- #include <sys/sockio.h>
- ***************
- *** 56,65 ****
- --- 57,80 ----
- #include <dev/pci/pcivar.h>
- #include <dev/ral/rt2560var.h>
- #include <dev/ral/rt2661var.h>
- + /* RT2860 includes */
- + #include <dev/ral/rt2860_softc.h>
- + #include <dev/ral/rt2860_reg.h>
- + #include <dev/ral/rt2860_eeprom.h>
- + #include <dev/ral/rt2860_ucode.h>
- + #include <dev/ral/rt2860_txwi.h>
- + #include <dev/ral/rt2860_rxwi.h>
- + #include <dev/ral/rt2860_io.h>
- + #include <dev/ral/rt2860_read_eeprom.h>
- + #include <dev/ral/rt2860_led.h>
- + #include <dev/ral/rt2860_rf.h>
- + #include <dev/ral/rt2860_debug.h>
- +
- +
- MODULE_DEPEND(ral, pci, 1, 1, 1);
- MODULE_DEPEND(ral, firmware, 1, 1, 1);
- MODULE_DEPEND(ral, wlan, 1, 1, 1);
- MODULE_DEPEND(ral, wlan_amrr, 1, 1, 1);
- ***************
- *** 67,82 ****
- uint16_t vendor;
- uint16_t device;
- const char *name;
- };
- static const struct ral_pci_ident ral_pci_ids[] = {
- { 0x1814, 0x0201, "Ralink Technology RT2560" },
- { 0x1814, 0x0301, "Ralink Technology RT2561S" },
- { 0x1814, 0x0302, "Ralink Technology RT2561" },
- { 0x1814, 0x0401, "Ralink Technology RT2661" },
- !
- { 0, 0, NULL }
- };
- static struct ral_opns {
- int (*attach)(device_t, int);
- --- 82,108 ----
- uint16_t vendor;
- uint16_t device;
- const char *name;
- };
- + #define PCI_VENDOR_RALINK 0x1814
- + #define PCI_PRODUCT_RALINK_RT2860_PCI 0x0601
- + #define PCI_PRODUCT_RALINK_RT2860_PCIe 0x0681
- + #define PCI_PRODUCT_RALINK_RT2760_PCI 0x0701
- + #define PCI_PRODUCT_RALINK_RT2790_PCIe 0x0781
- + #define PCI_PRODUCT_RALINK_RT3090_PCIe 0x3090
- +
- static const struct ral_pci_ident ral_pci_ids[] = {
- { 0x1814, 0x0201, "Ralink Technology RT2560" },
- { 0x1814, 0x0301, "Ralink Technology RT2561S" },
- { 0x1814, 0x0302, "Ralink Technology RT2561" },
- { 0x1814, 0x0401, "Ralink Technology RT2661" },
- ! { 0x1814, 0x0601, "Ralink Technology RT2860" },
- ! { 0x1814, 0x0681, "Ralink Technology RT2860" },
- ! { 0x1814, 0x0701, "Ralink Technology RT2760" },
- ! { 0x1814, 0x0781, "Ralink Technology RT2790" },
- ! { 0x1814, 0x3090, "Ralink Technology RT3090" },
- { 0, 0, NULL }
- };
- static struct ral_opns {
- int (*attach)(device_t, int);
- ***************
- *** 99,114 ****
- --- 125,150 ----
- rt2661_detach,
- rt2661_shutdown,
- rt2661_suspend,
- rt2661_resume,
- rt2661_intr
- +
- + }, ral_rt2860_opns = {
- + rt2860_attach,
- + rt2860_detach,
- + rt2860_shutdown,
- + rt2860_suspend,
- + rt2860_resume,
- + rt2860_intr
- +
- };
- struct ral_pci_softc {
- union {
- struct rt2560_softc sc_rt2560;
- struct rt2661_softc sc_rt2661;
- + struct rt2860_softc sc_rt2860;
- } u;
- struct ral_opns *sc_opns;
- int irq_rid;
- int mem_rid;
- ***************
- *** 178,190 ****
- --- 214,247 ----
- }
- /* enable bus-mastering */
- pci_enable_busmaster(dev);
- + /*
- psc->sc_opns = (pci_get_device(dev) == 0x0201) ? &ral_rt2560_opns :
- &ral_rt2661_opns;
- + */
- + if (pci_get_vendor(dev) == PCI_VENDOR_RALINK) {
- + switch (pci_get_device(dev)) {
- + case 0x2560:
- + psc->sc_opns = &ral_rt2560_opns;
- + break;
- + case 0x2561:
- + case 0x2562: /*rt2561s these are all invalid codes to avoid -Werror crap from clang */
- + case 0x2661:
- + psc->sc_opns = &ral_rt2661_opns;
- + break;
- + default:
- + psc->sc_opns = &ral_rt2860_opns;
- + break;
- + }
- + } else {
- + /* all other vendors are RT2860 only */
- +
- + psc->sc_opns = &ral_rt2860_opns;
- + }
- psc->mem_rid = RAL_PCI_BAR0;
- psc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &psc->mem_rid,
- RF_ACTIVE);
- if (psc->mem == NULL) {
- device_printf(dev, "could not allocate memory resource\n");
- ***************
- *** 205,219 ****
- --- 262,281 ----
- error = (*psc->sc_opns->attach)(dev, pci_get_device(dev));
- if (error != 0)
- return error;
- +
- +
- /*
- * Hook our interrupt after all initialization is complete.
- */
- +
- error = bus_setup_intr(dev, psc->irq, INTR_TYPE_NET | INTR_MPSAFE,
- NULL, psc->sc_opns->intr, psc, &psc->sc_ih);
- +
- +
- if (error != 0) {
- device_printf(dev, "could not set up interrupt\n");
- return error;
- }
- sc->sc_invalid = 0;
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860.c Mon Jun 6 17:29:30 2011
- ***************
- *** 0 ****
- --- 1,9849 ----
- +
- + /*-
- + * Copyright (c) 2009-2010 Alexander Egorenkov <[email protected]>
- + * Copyright (c) 2009 Damien Bergamini <[email protected]>
- + * Minor changes and bugs added by Matt <[email protected]>
- + * 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.
- + */
- +
- + #include <sys/param.h>
- + #include <sys/kernel.h>
- + #include <sys/module.h>
- + #include <sys/socket.h>
- + #include <sys/sysctl.h>
- + #include <net/if.h>
- + #include <net/if_media.h>
- + #include <dev/pci/pcireg.h>
- + #include <dev/pci/pcivar.h>
- + #include <net80211/ieee80211_var.h>
- + #include <dev/ral/rt2860_softc.h>
- + #include <dev/ral/rt2860_reg.h>
- + #include <dev/ral/rt2860_eeprom.h>
- + #include <dev/ral/rt2860_ucode.h>
- + #include <dev/ral/rt2860_txwi.h>
- + #include <dev/ral/rt2860_rxwi.h>
- + #include <dev/ral/rt2860_io.h>
- + #include <dev/ral/rt2860_read_eeprom.h>
- + #include <dev/ral/rt2860_led.h>
- + #include <dev/ral/rt2860_rf.h>
- + #include <dev/ral/rt2860_debug.h>
- + #include <dev/ral/rt2860_amrr.h>
- +
- + /*
- + * Defines and macros (General)
- + */
- +
- + #define RT2860_MAX_AGG_SIZE 3840
- +
- + #define RT2860_TX_DATA_SEG0_SIZE \
- + (sizeof(struct rt2860_txwi) + sizeof(struct ieee80211_qosframe_addr4))
- +
- + #define RT2860_NOISE_FLOOR -95
- +
- + #define IEEE80211_HAS_ADDR4(wh) \
- + (((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
- +
- + #define RT2860_MS(_v, _f) (((_v) & _f) >> _f##_S)
- + #define RT2860_SM(_v, _f) (((_v) << _f##_S) & _f)
- +
- + #define RT2860_TX_WATCHDOG_TIMEOUT 5
- +
- + #define RT2860_WCID_RESERVED 0xff
- + #define RT2860_WCID_MCAST 0xf7
- +
- + #define RT2860_IO_EEPROM_RAISE_CLK(sc, val) \
- + do \
- + { \
- + (val) |= RT2860_REG_EESK; \
- + \
- + rt2860_io_mac_write((sc), RT2860_REG_EEPROM_CSR, (val)); \
- + \
- + DELAY(1); \
- + } while (0)
- +
- + /*
- + * RT2860_IO_EEPROM_LOWER_CLK
- + */
- + #define RT2860_IO_EEPROM_LOWER_CLK(sc, val) \
- + do \
- + { \
- + (val) &= ~RT2860_REG_EESK; \
- + \
- + rt2860_io_mac_write((sc), RT2860_REG_EEPROM_CSR, (val)); \
- + \
- + DELAY(1); \
- + } while (0)
- +
- + #define RT2860_IO_BYTE_CRC16(byte, crc) \
- + ((uint16_t) (((crc) << 8) ^ rt2860_io_ccitt16[(((crc) >> 8) ^ (byte)) & 255]))
- +
- + /*
- + * Vendor IDs for various cards/chipsets
- + */
- + #define PCI_VENDOR_RALINK 0x1814
- + #define PCI_PRODUCT_RALINK_RT2860_PCI 0x0601
- + #define PCI_PRODUCT_RALINK_RT2860_PCIe 0x0681
- + #define PCI_PRODUCT_RALINK_RT2760_PCI 0x0701
- + #define PCI_PRODUCT_RALINK_RT2790_PCIe 0x0781
- + #define PCI_PRODUCT_RALINK_RT3090_PCIe 0x3090
- +
- + /*
- + * AMRR Defines
- + */
- +
- + #define RT2860_AMRR_IS_SUCCESS(amrr_node) ((amrr_node)->retrycnt < (amrr_node)->txcnt / 10)
- +
- + #define RT2860_AMRR_IS_FAILURE(amrr_node) ((amrr_node)->retrycnt > (amrr_node)->txcnt / 3)
- +
- + #define RT2860_AMRR_IS_ENOUGH(amrr_node) ((amrr_node)->txcnt > 10)
- +
- +
- + /*
- + * Global function prototypes, used in bus depended interfaces
- +
- + int rt2860_attach(device_t dev);
- +
- + int rt2860_detach(device_t dev);
- +
- + int rt2860_shutdown(device_t dev);
- +
- + int rt2860_suspend(device_t dev);
- +
- + int rt2860_resume(device_t dev);
- + */
- +
- + /*
- + * Static function prototypes
- + */
- +
- + static void rt2860_init_channels(struct rt2860_softc *sc);
- +
- + static void rt2860_init_channels_ht40(struct rt2860_softc *sc);
- +
- + static void rt2860_init_locked(void *priv);
- +
- + static void rt2860_init(void *priv);
- +
- + static int rt2860_init_bbp(struct rt2860_softc *sc);
- +
- + static void rt2860_stop_locked(void *priv);
- +
- + static void rt2860_stop(void *priv);
- +
- + static void rt2860_start(struct ifnet *ifp);
- +
- + static int rt2860_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
- +
- + static struct ieee80211vap *rt2860_vap_create(struct ieee80211com *ic,
- + const char name[IFNAMSIZ], int unit, int opmode, int flags,
- + const uint8_t bssid[IEEE80211_ADDR_LEN],
- + const uint8_t mac[IEEE80211_ADDR_LEN]);
- +
- + static void rt2860_vap_delete(struct ieee80211vap *vap);
- +
- + static int rt2860_vap_reset(struct ieee80211vap *vap, u_long cmd);
- +
- + static int rt2860_vap_newstate(struct ieee80211vap *vap,
- + enum ieee80211_state nstate, int arg);
- +
- + static void rt2860_vap_key_update_begin(struct ieee80211vap *vap);
- +
- + static void rt2860_vap_key_update_end(struct ieee80211vap *vap);
- +
- + static int rt2860_vap_key_set(struct ieee80211vap *vap,
- + const struct ieee80211_key *k, const uint8_t mac[IEEE80211_ADDR_LEN]);
- +
- + static int rt2860_vap_key_delete(struct ieee80211vap *vap,
- + const struct ieee80211_key *k);
- +
- + static void rt2860_vap_update_beacon(struct ieee80211vap *vap, int what);
- +
- + static int rt2860_media_change(struct ifnet *ifp);
- +
- + static struct ieee80211_node *rt2860_node_alloc(struct ieee80211vap *vap,
- + const uint8_t mac[IEEE80211_ADDR_LEN]);
- +
- + static void rt2860_node_cleanup(struct ieee80211_node *ni);
- +
- + static void rt2860_node_getmimoinfo(const struct ieee80211_node *ni,
- + struct ieee80211_mimo_info *mi);
- +
- + static int rt2860_setregdomain(struct ieee80211com *ic,
- + struct ieee80211_regdomain *reg,
- + int nchans, struct ieee80211_channel chans[]);
- +
- + static void rt2860_getradiocaps(struct ieee80211com *ic,
- + int maxchans, int *nchans, struct ieee80211_channel chans[]);
- +
- + static void rt2860_scan_start(struct ieee80211com *ic);
- +
- + static void rt2860_scan_end(struct ieee80211com *ic);
- +
- + static void rt2860_set_channel(struct ieee80211com *ic);
- +
- + static void rt2860_newassoc(struct ieee80211_node *ni, int isnew);
- +
- + static void rt2860_updateslot(struct ifnet *ifp);
- +
- + static void rt2860_update_promisc(struct ifnet *ifp);
- +
- + static void rt2860_update_mcast(struct ifnet *ifp);
- +
- + static int rt2860_wme_update(struct ieee80211com *ic);
- +
- + static int rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
- + const struct ieee80211_bpf_params *params);
- +
- + static int rt2860_recv_action(struct ieee80211_node *ni,
- + const struct ieee80211_frame *wh,
- + const uint8_t *frm, const uint8_t *efrm);
- +
- + static int rt2860_send_action(struct ieee80211_node *ni,
- + int cat, int act, void *sa);
- +
- + static int rt2860_addba_response(struct ieee80211_node *ni,
- + struct ieee80211_tx_ampdu *tap,
- + int status, int baparamset, int batimeout);
- +
- + static void rt2860_addba_stop(struct ieee80211_node *ni,
- + struct ieee80211_tx_ampdu *tap);
- +
- + static int rt2860_ampdu_rx_start(struct ieee80211_node *ni,
- + struct ieee80211_rx_ampdu *rap,
- + int baparamset, int batimeout, int baseqctl);
- +
- + static void rt2860_ampdu_rx_stop(struct ieee80211_node *ni,
- + struct ieee80211_rx_ampdu *rap);
- +
- + static int rt2860_send_bar(struct ieee80211_node *ni,
- + struct ieee80211_tx_ampdu *tap, ieee80211_seq seqno);
- +
- + static void rt2860_amrr_update_iter_func(void *arg, struct ieee80211_node *ni);
- +
- + static void rt2860_periodic(void *arg);
- +
- + static void rt2860_tx_watchdog(void *arg);
- +
- + static int rt2860_staid_alloc(struct rt2860_softc *sc, int aid);
- +
- + static void rt2860_staid_delete(struct rt2860_softc *sc, int staid);
- +
- + static void rt2860_asic_set_bssid(struct rt2860_softc *sc,
- + const uint8_t *bssid);
- +
- + static void rt2860_asic_set_macaddr(struct rt2860_softc *sc,
- + const uint8_t *addr);
- +
- + static void rt2860_asic_enable_tsf_sync(struct rt2860_softc *sc);
- +
- + static void rt2860_asic_disable_tsf_sync(struct rt2860_softc *sc);
- +
- + static void rt2860_asic_enable_mrr(struct rt2860_softc *sc);
- +
- + static void rt2860_asic_set_txpreamble(struct rt2860_softc *sc);
- +
- + static void rt2860_asic_set_basicrates(struct rt2860_softc *sc);
- +
- + static void rt2860_asic_update_rtsthreshold(struct rt2860_softc *sc);
- +
- + static void rt2860_asic_update_txpower(struct rt2860_softc *sc);
- +
- + static void rt2860_asic_update_promisc(struct rt2860_softc *sc);
- +
- + static void rt2860_asic_updateprot(struct rt2860_softc *sc);
- +
- + static void rt2860_asic_updateslot(struct rt2860_softc *sc);
- +
- + static void rt2860_asic_wme_update(struct rt2860_softc *sc);
- +
- + static void rt2860_asic_update_beacon(struct rt2860_softc *sc,
- + struct ieee80211vap *vap);
- +
- + static void rt2860_asic_clear_keytables(struct rt2860_softc *sc);
- +
- + static void rt2860_asic_add_ba_session(struct rt2860_softc *sc,
- + uint8_t wcid, int tid);
- +
- + static void rt2860_asic_del_ba_session(struct rt2860_softc *sc,
- + uint8_t wcid, int tid);
- +
- + static int rt2860_beacon_alloc(struct rt2860_softc *sc,
- + struct ieee80211vap *vap);
- +
- + static uint8_t rt2860_rxrate(struct rt2860_rxwi *rxwi);
- +
- + static uint8_t rt2860_maxrssi_rxpath(struct rt2860_softc *sc,
- + const struct rt2860_rxwi *rxwi);
- +
- + static int8_t rt2860_rssi2dbm(struct rt2860_softc *sc,
- + uint8_t rssi, uint8_t rxpath);
- +
- + static uint8_t rt2860_rate2mcs(uint8_t rate);
- +
- + static int rt2860_tx_mgmt(struct rt2860_softc *sc,
- + struct mbuf *m, struct ieee80211_node *ni, int qid);
- +
- + static int rt2860_tx_data(struct rt2860_softc *sc,
- + struct mbuf *m, struct ieee80211_node *ni, int qid);
- +
- + /*
- + static int rt2860_tx_raw(struct rt2860_softc *sc,
- + struct mbuf *m, struct ieee80211_node *ni,
- + const struct ieee80211_bpf_params *params);
- + */
- +
- + static int rt2860_amrr_update(struct rt2860_amrr *amrr,
- + struct rt2860_amrr_node *amrr_node, struct ieee80211_node *ni);
- +
- + /* Declared elsewheres rt2860_softc.h */
- + /* static void rt2860_intr(void *arg); */
- +
- + static void rt2860_tx_coherent_intr(struct rt2860_softc *sc);
- +
- + static void rt2860_rx_coherent_intr(struct rt2860_softc *sc);
- +
- + static void rt2860_txrx_coherent_intr(struct rt2860_softc *sc);
- +
- + static void rt2860_fifo_sta_full_intr(struct rt2860_softc *sc);
- +
- + static void rt2860_rx_intr(struct rt2860_softc *sc);
- +
- + static void rt2860_rx_delay_intr(struct rt2860_softc *sc);
- +
- + static void rt2860_tx_intr(struct rt2860_softc *sc, int qid);
- +
- + static void rt2860_tx_delay_intr(struct rt2860_softc *sc);
- +
- + static void rt2860_pre_tbtt_intr(struct rt2860_softc *sc);
- +
- + static void rt2860_tbtt_intr(struct rt2860_softc *sc);
- +
- + static void rt2860_mcu_cmd_intr(struct rt2860_softc *sc);
- +
- + static void rt2860_auto_wakeup_intr(struct rt2860_softc *sc);
- +
- + static void rt2860_gp_timer_intr(struct rt2860_softc *sc);
- +
- + static void rt2860_rx_done_task(void *context, int pending);
- +
- + static void rt2860_tx_done_task(void *context, int pending);
- +
- + static void rt2860_fifo_sta_full_task(void *context, int pending);
- +
- + static void rt2860_periodic_task(void *context, int pending);
- +
- + static int rt2860_rx_eof(struct rt2860_softc *sc, int limit);
- +
- + static void rt2860_tx_eof(struct rt2860_softc *sc,
- + struct rt2860_softc_tx_ring *ring);
- +
- + static void rt2860_update_stats(struct rt2860_softc *sc);
- +
- + static void rt2860_bbp_tuning(struct rt2860_softc *sc);
- +
- + static void rt2860_watchdog(struct rt2860_softc *sc);
- +
- + static void rt2860_drain_fifo_stats(struct rt2860_softc *sc);
- +
- + static void rt2860_update_raw_counters(struct rt2860_softc *sc);
- +
- + static void rt2860_intr_enable(struct rt2860_softc *sc, uint32_t intr_mask);
- +
- + static void rt2860_intr_disable(struct rt2860_softc *sc, uint32_t intr_mask);
- +
- + static int rt2860_txrx_enable(struct rt2860_softc *sc);
- +
- + static int rt2860_alloc_rx_ring(struct rt2860_softc *sc,
- + struct rt2860_softc_rx_ring *ring);
- +
- + static void rt2860_reset_rx_ring(struct rt2860_softc *sc,
- + struct rt2860_softc_rx_ring *ring);
- +
- + static void rt2860_free_rx_ring(struct rt2860_softc *sc,
- + struct rt2860_softc_rx_ring *ring);
- +
- + static int rt2860_alloc_tx_ring(struct rt2860_softc *sc,
- + struct rt2860_softc_tx_ring *ring, int qid);
- +
- + static void rt2860_reset_tx_ring(struct rt2860_softc *sc,
- + struct rt2860_softc_tx_ring *ring);
- +
- + static void rt2860_free_tx_ring(struct rt2860_softc *sc,
- + struct rt2860_softc_tx_ring *ring);
- +
- + static void rt2860_dma_map_addr(void *arg, bus_dma_segment_t *segs,
- + int nseg, int error);
- +
- + static void rt2860_sysctl_attach(struct rt2860_softc *sc);
- +
- + static void rt2860_io_eeprom_shiftout_bits(struct rt2860_softc *sc,
- + uint16_t val, uint16_t count);
- +
- + static uint16_t rt2860_io_eeprom_shiftin_bits(struct rt2860_softc *sc);
- +
- + static uint8_t rt2860_io_byte_rev(uint8_t byte);
- +
- + static void rt2872_rf_set_chan(struct rt2860_softc *sc, struct ieee80211_channel *c);
- +
- + /*
- + * Static variables
- + */
- +
- + extern uint8_t rt3052_rf_default[];
- +
- + static const struct rt2860_rf_prog
- + {
- + uint8_t chan;
- + uint32_t r1, r2, r3, r4;
- + } rt2860_rf_2850[] =
- + {
- + { 1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b },
- + { 2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f },
- + { 3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b },
- + { 4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f },
- + { 5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b },
- + { 6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f },
- + { 7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b },
- + { 8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f },
- + { 9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b },
- + { 10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f },
- + { 11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b },
- + { 12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f },
- + { 13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b },
- + { 14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193 },
- + { 36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3 },
- + { 38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193 },
- + { 40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183 },
- + { 44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3 },
- + { 46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b },
- + { 48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b },
- + { 52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193 },
- + { 54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3 },
- + { 56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b },
- + { 60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183 },
- + { 62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193 },
- + { 64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3 },
- + { 100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783 },
- + { 102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793 },
- + { 104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3 },
- + { 108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193 },
- + { 110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183 },
- + { 112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b },
- + { 116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3 },
- + { 118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193 },
- + { 120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183 },
- + { 124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193 },
- + { 126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b },
- + { 128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3 },
- + { 132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b },
- + { 134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193 },
- + { 136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b },
- + { 140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183 },
- + { 149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7 },
- + { 151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187 },
- + { 153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f },
- + { 157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f },
- + { 159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7 },
- + { 161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187 },
- + { 165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197 },
- + { 184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b },
- + { 188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13 },
- + { 192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b },
- + { 196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23 },
- + { 208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13 },
- + { 212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b },
- + { 216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23 },
- + };
- +
- + static const struct rfprog {
- + uint8_t chan;
- + uint32_t r1, r2, r3, r4;
- + } rt2860_rf2850[] = {
- + { 1, 0x100bb3, 0x1301e1, 0x05a014, 0x001402 },
- + { 2, 0x100bb3, 0x1301e1, 0x05a014, 0x001407 },
- + { 3, 0x100bb3, 0x1301e2, 0x05a014, 0x001402 },
- + { 4, 0x100bb3, 0x1301e2, 0x05a014, 0x001407 },
- + { 5, 0x100bb3, 0x1301e3, 0x05a014, 0x001402 },
- + { 6, 0x100bb3, 0x1301e3, 0x05a014, 0x001407 },
- + { 7, 0x100bb3, 0x1301e4, 0x05a014, 0x001402 },
- + { 8, 0x100bb3, 0x1301e4, 0x05a014, 0x001407 },
- + { 9, 0x100bb3, 0x1301e5, 0x05a014, 0x001402 },
- + { 10, 0x100bb3, 0x1301e5, 0x05a014, 0x001407 },
- + { 11, 0x100bb3, 0x1301e6, 0x05a014, 0x001402 },
- + { 12, 0x100bb3, 0x1301e6, 0x05a014, 0x001407 },
- + { 13, 0x100bb3, 0x1301e7, 0x05a014, 0x001402 },
- + { 14, 0x100bb3, 0x1301e8, 0x05a014, 0x001404 },
- + { 36, 0x100bb3, 0x130266, 0x056014, 0x001408 },
- + { 38, 0x100bb3, 0x130267, 0x056014, 0x001404 },
- + { 40, 0x100bb2, 0x1301a0, 0x056014, 0x001400 },
- + { 44, 0x100bb2, 0x1301a0, 0x056014, 0x001408 },
- + { 46, 0x100bb2, 0x1301a1, 0x056014, 0x001402 },
- + { 48, 0x100bb2, 0x1301a1, 0x056014, 0x001406 },
- + { 52, 0x100bb2, 0x1301a2, 0x056014, 0x001404 },
- + { 54, 0x100bb2, 0x1301a2, 0x056014, 0x001408 },
- + { 56, 0x100bb2, 0x1301a3, 0x056014, 0x001402 },
- + { 60, 0x100bb2, 0x1301a4, 0x056014, 0x001400 },
- + { 62, 0x100bb2, 0x1301a4, 0x056014, 0x001404 },
- + { 64, 0x100bb2, 0x1301a4, 0x056014, 0x001408 },
- + { 100, 0x100bb2, 0x1301ac, 0x05e014, 0x001400 },
- + { 102, 0x100bb2, 0x1701ac, 0x15e014, 0x001404 },
- + { 104, 0x100bb2, 0x1701ac, 0x15e014, 0x001408 },
- + { 108, 0x100bb3, 0x17028c, 0x15e014, 0x001404 },
- + { 110, 0x100bb3, 0x13028d, 0x05e014, 0x001400 },
- + { 112, 0x100bb3, 0x13028d, 0x05e014, 0x001406 },
- + { 116, 0x100bb3, 0x13028e, 0x05e014, 0x001408 },
- + { 118, 0x100bb3, 0x13028f, 0x05e014, 0x001404 },
- + { 120, 0x100bb1, 0x1300e0, 0x05e014, 0x001400 },
- + { 124, 0x100bb1, 0x1300e0, 0x05e014, 0x001404 },
- + { 126, 0x100bb1, 0x1300e0, 0x05e014, 0x001406 },
- + { 128, 0x100bb1, 0x1300e0, 0x05e014, 0x001408 },
- + { 132, 0x100bb1, 0x1300e1, 0x05e014, 0x001402 },
- + { 134, 0x100bb1, 0x1300e1, 0x05e014, 0x001404 },
- + { 136, 0x100bb1, 0x1300e1, 0x05e014, 0x001406 },
- + { 140, 0x100bb1, 0x1300e2, 0x05e014, 0x001400 },
- + { 149, 0x100bb1, 0x1300e2, 0x05e014, 0x001409 },
- + { 151, 0x100bb1, 0x1300e3, 0x05e014, 0x001401 },
- + { 153, 0x100bb1, 0x1300e3, 0x05e014, 0x001403 },
- + { 157, 0x100bb1, 0x1300e3, 0x05e014, 0x001407 },
- + { 159, 0x100bb1, 0x1300e3, 0x05e014, 0x001409 },
- + { 161, 0x100bb1, 0x1300e4, 0x05e014, 0x001401 },
- + { 165, 0x100bb1, 0x1300e4, 0x05e014, 0x001405 },
- + { 167, 0x100bb1, 0x1300f4, 0x05e014, 0x001407 },
- + { 169, 0x100bb1, 0x1300f4, 0x05e014, 0x001409 },
- + { 171, 0x100bb1, 0x1300f5, 0x05e014, 0x001401 },
- + { 173, 0x100bb1, 0x1300f5, 0x05e014, 0x001403 }
- + };
- +
- + static const struct rt2860_rf_fi3020
- + {
- + uint8_t channel, n, r, k;
- + } rt2860_rf_fi3020[] =
- + {
- + /* 802.11g */
- + {1, 241, 2, 2},
- + {2, 241, 2, 7},
- + {3, 242, 2, 2},
- + {4, 242, 2, 7},
- + {5, 243, 2, 2},
- + {6, 243, 2, 7},
- + {7, 244, 2, 2},
- + {8, 244, 2, 7},
- + {9, 245, 2, 2},
- + {10, 245, 2, 7},
- + {11, 246, 2, 2},
- + {12, 246, 2, 7},
- + {13, 247, 2, 2},
- + {14, 248, 2, 4},
- +
- + /* 802.11 UNI / HyperLan 2 */
- + {36, 0x56, 0, 4},
- + {38, 0x56, 0, 6},
- + {40, 0x56, 0, 8},
- + {44, 0x57, 0, 0},
- + {46, 0x57, 0, 2},
- + {48, 0x57, 0, 4},
- + {52, 0x57, 0, 8},
- + {54, 0x57, 0, 10},
- + {56, 0x58, 0, 0},
- + {60, 0x58, 0, 4},
- + {62, 0x58, 0, 6},
- + {64, 0x58, 0, 8},
- +
- + /* 802.11 HyperLan 2 */
- + {100, 0x5b, 0, 8},
- + {102, 0x5b, 0, 10},
- + {104, 0x5c, 0, 0},
- + {108, 0x5c, 0, 4},
- + {110, 0x5c, 0, 6},
- + {112, 0x5c, 0, 8},
- + {116, 0x5d, 0, 0},
- + {118, 0x5d, 0, 2},
- + {120, 0x5d, 0, 4},
- + {124, 0x5d, 0, 8},
- + {126, 0x5d, 0, 10},
- + {128, 0x5e, 0, 0},
- + {132, 0x5e, 0, 4},
- + {134, 0x5e, 0, 6},
- + {136, 0x5e, 0, 8},
- + {140, 0x5f, 0, 0},
- +
- + /* 802.11 UNII */
- + {149, 0x5f, 0, 9},
- + {151, 0x5f, 0, 11},
- + {153, 0x60, 0, 1},
- + {157, 0x60, 0, 5},
- + {159, 0x60, 0, 7},
- + {161, 0x60, 0, 9},
- + {165, 0x61, 0, 1},
- + {167, 0x61, 0, 3},
- + {169, 0x61, 0, 5},
- + {171, 0x61, 0, 7},
- + {173, 0x61, 0, 9},
- + };
- +
- + static const struct {
- + uint8_t reg;
- + uint8_t val;
- + } rt3090_def_rf[] = {
- + { 4, 0x40 },
- + { 5, 0x03 },
- + { 6, 0x02 },
- + { 7, 0x70 },
- + { 9, 0x0f },
- + { 10, 0x41 },
- + { 11, 0x21 },
- + { 12, 0x7b },
- + { 14, 0x90 },
- + { 15, 0x58 },
- + { 16, 0xb3 },
- + { 17, 0x92 },
- + { 18, 0x2c },
- + { 19, 0x02 },
- + { 20, 0xba },
- + { 21, 0xdb },
- + { 24, 0x16 },
- + { 25, 0x01 },
- + { 29, 0x1f }
- + };
- +
- + struct {
- + uint8_t n, r, k;
- + } rt3090_freqs[] = {
- + { 0xf1, 2, 2 },
- + { 0xf1, 2, 7 },
- + { 0xf2, 2, 2 },
- + { 0xf2, 2, 7 },
- + { 0xf3, 2, 2 },
- + { 0xf3, 2, 7 },
- + { 0xf4, 2, 2 },
- + { 0xf4, 2, 7 },
- + { 0xf5, 2, 2 },
- + { 0xf5, 2, 7 },
- + { 0xf6, 2, 2 },
- + { 0xf6, 2, 7 },
- + { 0xf7, 2, 2 },
- + { 0xf8, 2, 4 },
- + { 0x56, 0, 4 },
- + { 0x56, 0, 6 },
- + { 0x56, 0, 8 },
- + { 0x57, 0, 0 },
- + { 0x57, 0, 2 },
- + { 0x57, 0, 4 },
- + { 0x57, 0, 8 },
- + { 0x57, 0, 10 },
- + { 0x58, 0, 0 },
- + { 0x58, 0, 4 },
- + { 0x58, 0, 6 },
- + { 0x58, 0, 8 },
- + { 0x5b, 0, 8 },
- + { 0x5b, 0, 10 },
- + { 0x5c, 0, 0 },
- + { 0x5c, 0, 4 },
- + { 0x5c, 0, 6 },
- + { 0x5c, 0, 8 },
- + { 0x5d, 0, 0 },
- + { 0x5d, 0, 2 },
- + { 0x5d, 0, 4 },
- + { 0x5d, 0, 8 },
- + { 0x5d, 0, 10 },
- + { 0x5e, 0, 0 },
- + { 0x5e, 0, 4 },
- + { 0x5e, 0, 6 },
- + { 0x5e, 0, 8 },
- + { 0x5f, 0, 0 },
- + { 0x5f, 0, 9 },
- + { 0x5f, 0, 11 },
- + { 0x60, 0, 1 },
- + { 0x60, 0, 5 },
- + { 0x60, 0, 7 },
- + { 0x60, 0, 9 },
- + { 0x61, 0, 1 },
- + { 0x61, 0, 3 },
- + { 0x61, 0, 5 },
- + { 0x61, 0, 7 },
- + { 0x61, 0, 9 }
- + };
- +
- + /* #ifdef RT305X_SOC */
- + static const uint16_t rt3052_eeprom[] =
- + {
- + 0x3052, 0x0101, 0x0c00, 0x3043, 0x8852, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0x0c00, 0x3043, 0x7752, 0x0c00,
- + 0x3043, 0x6652, 0x0822, 0x0024, 0xffff, 0x012f, 0x7755, 0xaaa8,
- + 0x888c, 0xffff, 0x000c, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff,
- + 0xffff, 0x0d0d, 0x0d0d, 0x0c0c, 0x0c0c, 0x0c0c, 0x0c0c, 0x0c0c,
- + 0x1010, 0x1111, 0x1211, 0x1212, 0x1313, 0x1413, 0x1414, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6666,
- + 0xaacc, 0x6688, 0xaacc, 0x6688, 0xaacc, 0x6688, 0xaacc, 0x6688,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- + };
- +
- + uint8_t rt3052_rf_default[] = {
- + 0x50,
- + 0x01,
- + 0xF7,
- + 0x75,
- + 0x40,
- + 0x03,
- + 0x42,
- + 0x50,
- + 0x39,
- + 0x0F,
- + 0x60,
- + 0x21,
- + 0x75,
- + 0x75,
- + 0x90,
- + 0x58,
- + 0xB3,
- + 0x92,
- + 0x2C,
- + 0x02,
- + 0xBA,
- + 0xDB,
- + 0x00,
- + 0x31,
- + 0x08,
- + 0x01,
- + 0x25, /* Core Power: 0x25=1.25V */
- + 0x23, /* RF: 1.35V */
- + 0x13, /* ADC: must consist with R27 */
- + 0x83,
- + 0x00,
- + 0x00,
- + };
- + /* #endif */
- +
- + static const uint16_t rt2860_io_ccitt16[] =
- + {
- + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
- + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
- + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
- + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
- + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
- + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
- + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
- + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
- + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
- + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
- + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
- + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
- + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
- + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
- + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
- + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
- + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
- + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
- + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
- + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
- + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
- + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
- + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
- + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
- + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
- + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
- + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
- + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
- + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
- + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
- + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
- + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
- + };
- +
- + static const struct
- + {
- + uint32_t reg;
- + uint32_t val;
- + } rt2860_def_mac[] =
- + {
- + { RT2860_REG_PBF_BCN_OFFSET0, 0xf8f0e8e0 },
- + { RT2860_REG_PBF_BCN_OFFSET1, 0x6f77d0c8 },
- + { RT2860_REG_LEGACY_BASIC_RATE, 0x0000013f },
- + { RT2860_REG_HT_BASIC_RATE, 0x00008003 },
- + { RT2860_REG_SYS_CTRL, 0x00000000 },
- + { RT2860_REG_RX_FILTER_CFG, 0x00017f97 },
- + { RT2860_REG_BKOFF_SLOT_CFG, 0x00000209 },
- + { RT2860_REG_TX_SW_CFG0, 0x00000000 },
- + { RT2860_REG_TX_SW_CFG1, 0x00080606 },
- + { RT2860_REG_TX_LINK_CFG, 0x00001020 },
- + { RT2860_REG_TX_TIMEOUT_CFG, 0x000a2090 },
- + { RT2860_REG_MAX_LEN_CFG, (1 << 12) | RT2860_MAX_AGG_SIZE },
- + { RT2860_REG_LED_CFG, 0x7f031e46 },
- + { RT2860_REG_PBF_MAX_PCNT, 0x1f3fbf9f },
- + { RT2860_REG_TX_RTY_CFG, 0x47d01f0f },
- + { RT2860_REG_AUTO_RSP_CFG, 0x00000013 },
- + { RT2860_REG_TX_CCK_PROT_CFG, 0x05740003 },
- + { RT2860_REG_TX_OFDM_PROT_CFG, 0x05740003 },
- + { RT2860_REG_TX_GF20_PROT_CFG, 0x01744004 },
- + { RT2860_REG_TX_GF40_PROT_CFG, 0x03f44084 },
- + { RT2860_REG_TX_MM20_PROT_CFG, 0x01744004 },
- + { RT2860_REG_TX_MM40_PROT_CFG, 0x03f54084 },
- + { RT2860_REG_TX_TXOP_CTRL_CFG, 0x0000583f },
- + { RT2860_REG_TX_RTS_CFG, 0x00092b20 },
- + { RT2860_REG_TX_EXP_ACK_TIME, 0x002400ca },
- + { RT2860_REG_HCCAPSMP_TXOP_HLDR_ET, 0x00000002 },
- + { RT2860_REG_XIFS_TIME_CFG, 0x33a41010 },
- + { RT2860_REG_PWR_PIN_CFG, 0x00000003 },
- + { RT2860_REG_SCHDMA_WMM_AIFSN_CFG, 0x00002273 },
- + { RT2860_REG_SCHDMA_WMM_CWMIN_CFG, 0x00002344 },
- + { RT2860_REG_SCHDMA_WMM_CWMAX_CFG, 0x000034aa },
- + };
- +
- + #define RT2860_DEF_MAC_SIZE (sizeof(rt2860_def_mac) / sizeof(rt2860_def_mac[0]))
- +
- + static const struct
- + {
- + uint8_t reg;
- + uint8_t val;
- + } rt2860_def_bbp[] =
- + {
- + { 65, 0x2c },
- + { 66, 0x38 },
- + { 69, 0x12 },
- + { 70, 0x0a },
- + { 73, 0x10 },
- + { 81, 0x37 },
- + { 82, 0x62 },
- + { 83, 0x6a },
- + { 84, 0x99 },
- + { 86, 0x00 },
- + { 91, 0x04 },
- + { 92, 0x00 },
- + { 103, 0x00 },
- + { 105, 0x05 },
- + { 106, 0x35 },
- + };
- +
- + #define RT2860_DEF_BBP_SIZE (sizeof(rt2860_def_bbp) / sizeof(rt2860_def_bbp[0]))
- +
- + SYSCTL_NODE(_hw, OID_AUTO, rt2860, CTLFLAG_RD, 0, "RT2860 driver parameters");
- +
- + static int rt2860_tx_stbc = 1;
- + SYSCTL_INT(_hw_rt2860, OID_AUTO, tx_stbc, CTLFLAG_RW, &rt2860_tx_stbc, 0, "RT2860 Tx STBC");
- + TUNABLE_INT("hw.ral.2860_stbc", &rt2860_tx_stbc);
- +
- + #ifdef RT2860_DEBUG
- + static int rt2860_debug = 0;
- + SYSCTL_INT(_hw_rt2860, OID_AUTO, debug, CTLFLAG_RW, &rt2860_debug, 0, "RT2860 debug level");
- + TUNABLE_INT("hw.ral.2860_debug", &rt2860_debug);
- + #endif
- +
- + /*
- + * Chip/Board IO functions
- + */
- +
- +
- + /*
- + * rt2860_io_mac_read
- + */
- + uint32_t rt2860_io_mac_read(struct rt2860_softc *sc, uint16_t reg)
- + {
- + bus_space_read_4(sc->sc_st, sc->sc_sh, RT2860_REG_MAC_CSR0);
- + return bus_space_read_4(sc->sc_st, sc->sc_sh, reg);
- + }
- +
- + /*
- + * rt2860_io_mac_read_multi
- + */
- + void rt2860_io_mac_read_multi(struct rt2860_softc *sc,
- + uint16_t reg, void *buf, size_t len)
- + {
- + bus_space_read_4(sc->sc_st, sc->sc_sh, RT2860_REG_MAC_CSR0);
- + bus_space_read_region_1(sc->sc_st, sc->sc_sh, reg, buf, len);
- + }
- +
- + /*
- + * rt2860_io_mac_write
- + */
- + void rt2860_io_mac_write(struct rt2860_softc *sc,
- + uint16_t reg, uint32_t val)
- + {
- + bus_space_read_4(sc->sc_st, sc->sc_sh, RT2860_REG_MAC_CSR0);
- + bus_space_write_4(sc->sc_st, sc->sc_sh, reg, val);
- + }
- +
- + /*
- + * rt2860_io_mac_write_multi
- + */
- + void rt2860_io_mac_write_multi(struct rt2860_softc *sc,
- + uint16_t reg, const void *buf, size_t len)
- + {
- + int i;
- + const uint8_t *p;
- +
- + bus_space_read_4(sc->sc_st, sc->sc_sh, RT2860_REG_MAC_CSR0);
- +
- + p = buf;
- + for (i = 0; i < len; i ++)
- + bus_space_write_1(sc->sc_st, sc->sc_sh, reg + i, *(p+i));
- + #ifdef notyet
- + bus_space_write_region_1(sc->sc_st, sc->sc_sh, reg, buf, len);
- + #endif
- + }
- +
- + /*
- + * rt2860_io_mac_set_region_4
- + */
- + void rt2860_io_mac_set_region_4(struct rt2860_softc *sc,
- + uint16_t reg, uint32_t val, size_t len)
- + {
- + int i;
- +
- + for (i = 0; i < len; i += sizeof(uint32_t))
- + rt2860_io_mac_write(sc, reg + i, val);
- + }
- +
- + /* Read 16-bit from eFUSE ROM (>=RT3071 only.) */
- + static uint16_t
- + rt3090_efuse_read_2(struct rt2860_softc *sc, uint16_t addr)
- + {
- + uint32_t tmp;
- + uint16_t reg;
- + int ntries;
- +
- + addr *= 2;
- + /*-
- + * Read one 16-byte block into registers EFUSE_DATA[0-3]:
- + * DATA0: F E D C
- + * DATA1: B A 9 8
- + * DATA2: 7 6 5 4
- + * DATA3: 3 2 1 0
- + */
- + tmp = rt2860_io_mac_read(sc, RT3070_EFUSE_CTRL);
- + tmp &= ~(RT3070_EFSROM_MODE_MASK | RT3070_EFSROM_AIN_MASK);
- + tmp |= (addr & ~0xf) << RT3070_EFSROM_AIN_SHIFT | RT3070_EFSROM_KICK;
- + rt2860_io_mac_write(sc, RT3070_EFUSE_CTRL, tmp);
- + for (ntries = 0; ntries < 500; ntries++) {
- + tmp = rt2860_io_mac_read(sc, RT3070_EFUSE_CTRL);
- + if (!(tmp & RT3070_EFSROM_KICK))
- + break;
- + DELAY(2);
- + }
- + if (ntries == 500)
- + return 0xffff;
- +
- + if ((tmp & RT3070_EFUSE_AOUT_MASK) == RT3070_EFUSE_AOUT_MASK)
- + return 0xffff; /* address not found */
- +
- + /* determine to which 32-bit register our 16-bit word belongs */
- + reg = RT3070_EFUSE_DATA3 - (addr & 0xc);
- + tmp = rt2860_io_mac_read(sc, reg);
- +
- + return (addr & 2) ? tmp >> 16 : tmp & 0xffff;
- + }
- +
- +
- + /*
- + * rt2860_io_eeprom_read
- + */
- + uint16_t rt2860_io_eeprom_read(struct rt2860_softc *sc, uint16_t addr)
- + {
- + uint32_t tmp;
- + uint16_t val;
- +
- + addr = (addr >> 1);
- +
- + if (sc->mac_rev == 0x28720200) {
- + return (rt3052_eeprom[addr]);
- + } else if ((sc->mac_rev & 0xffff0000) >= 0x30710000) {
- + tmp = rt2860_io_mac_read(sc, RT3070_EFUSE_CTRL);
- + if (tmp & RT3070_SEL_EFUSE)
- + return (rt3090_efuse_read_2(sc, addr));
- + }
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR);
- +
- + tmp &= ~(RT2860_REG_EEDI | RT2860_REG_EEDO | RT2860_REG_EESK);
- + tmp |= RT2860_REG_EECS;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_EEPROM_CSR, tmp);
- +
- + if (((sc->mac_rev & 0xffff0000) != 0x30710000) &&
- + ((sc->mac_rev & 0xffff0000) != 0x30900000) &&
- + ((sc->mac_rev & 0xffff0000) != 0x35720000) &&
- + ((sc->mac_rev & 0xffff0000) != 0x33900000))
- + {
- + RT2860_IO_EEPROM_RAISE_CLK(sc, tmp);
- + RT2860_IO_EEPROM_LOWER_CLK(sc, tmp);
- + }
- +
- + rt2860_io_eeprom_shiftout_bits(sc, RT2860_REG_EEOP_READ, 3);
- + rt2860_io_eeprom_shiftout_bits(sc, addr, sc->eeprom_addr_num);
- +
- + val = rt2860_io_eeprom_shiftin_bits(sc);
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR);
- +
- + tmp &= ~(RT2860_REG_EECS | RT2860_REG_EEDI);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_EEPROM_CSR, tmp);
- +
- + RT2860_IO_EEPROM_RAISE_CLK(sc, tmp);
- + RT2860_IO_EEPROM_LOWER_CLK(sc, tmp);
- +
- + return val;
- + }
- +
- + /*
- + * rt2860_io_eeprom_read_multi
- + */
- + void rt2860_io_eeprom_read_multi(struct rt2860_softc *sc,
- + uint16_t addr, void *buf, size_t len)
- + {
- + uint16_t *ptr;
- + int i;
- +
- + len += len % sizeof(uint16_t);
- + ptr = buf;
- +
- + i = 0;
- +
- + do
- + {
- + *ptr++ = rt2860_io_eeprom_read(sc, addr + i);
- +
- + i += sizeof(uint16_t);
- + len -= sizeof(uint16_t);
- + } while (len > 0);
- + }
- +
- + /*
- + * rt2860_io_bbp_read
- + */
- + uint8_t rt2860_io_bbp_read(struct rt2860_softc *sc, uint8_t reg)
- + {
- + int ntries;
- + uint32_t tmp;
- +
- + if (sc->mac_rev == 0x28720200)
- + {
- + for (ntries = 0; ntries < 100; ntries ++) {
- + if ( !(rt2860_io_mac_read(sc, RT2860_REG_BBP_CSR_CFG) &
- + RT2860_REG_BBP_CSR_BUSY) )
- + break;
- + DELAY(1);
- + }
- + if (ntries == 100) {
- + printf("%s:%s: BBP busy after 100 probes\n",
- + device_get_nameunit(sc->sc_dev), __func__);
- + return (0);
- + }
- + rt2860_io_mac_write(sc, RT2860_REG_BBP_CSR_CFG,
- + RT2860_REG_BBP_CSR_READ |
- + RT2860_REG_BBP_CSR_KICK | RT2860_REG_BBP_RW_MODE_PARALLEL |
- + (reg & RT2860_REG_BBP_REG_MASK) << RT2860_REG_BBP_REG_SHIFT);
- + for (ntries = 0; ntries < 100; ntries ++) {
- + if ( !(rt2860_io_mac_read(sc, RT2860_REG_BBP_CSR_CFG) &
- + RT2860_REG_BBP_CSR_BUSY) )
- + break;
- + DELAY(1);
- + }
- + if (ntries == 100) {
- + printf("%s:%s: BBP busy after 100 probes\n",
- + device_get_nameunit(sc->sc_dev), __func__);
- + return (0);
- + }
- + else {
- + return
- + ((rt2860_io_mac_read(sc, RT2860_REG_BBP_CSR_CFG) >>
- + RT2860_REG_BBP_VAL_SHIFT) &
- + RT2860_REG_BBP_VAL_MASK);
- + }
- + return (0);
- + }
- +
- + for (ntries = 0; ntries < 100; ntries++)
- + {
- + if (!(rt2860_io_mac_read(sc, RT2860_REG_H2M_MAILBOX_BBP_AGENT) &
- + RT2860_REG_BBP_CSR_BUSY))
- + break;
- +
- + DELAY(1);
- + }
- +
- + if (ntries == 100)
- + {
- + printf("%s: could not read from BBP through MCU: reg=0x%02x\n",
- + device_get_nameunit(sc->sc_dev), reg);
- + return 0;
- + }
- +
- + tmp = RT2860_REG_BBP_RW_MODE_PARALLEL |
- + RT2860_REG_BBP_CSR_BUSY |
- + RT2860_REG_BBP_CSR_READ |
- + ((reg & RT2860_REG_BBP_REG_MASK) << RT2860_REG_BBP_REG_SHIFT);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX_BBP_AGENT, tmp);
- +
- + rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_BBP,
- + RT2860_REG_H2M_TOKEN_NO_INTR, 0);
- +
- + DELAY(1000);
- +
- + for (ntries = 0; ntries < 100; ntries++)
- + {
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_H2M_MAILBOX_BBP_AGENT);
- + if (!(tmp & RT2860_REG_BBP_CSR_BUSY))
- + return ((tmp >> RT2860_REG_BBP_VAL_SHIFT) &
- + RT2860_REG_BBP_VAL_MASK);
- +
- + DELAY(1);
- + }
- +
- + printf("%s: could not read from BBP through MCU: reg=0x%02x\n",
- + device_get_nameunit(sc->sc_dev), reg);
- +
- + return 0;
- + }
- +
- + /*
- + * rt2860_io_bbp_write
- + */
- + void rt2860_io_bbp_write(struct rt2860_softc *sc, uint8_t reg, uint8_t val)
- + {
- + int ntries;
- + uint32_t tmp;
- +
- + if (sc->mac_rev == 0x28720200)
- + {
- + for (ntries = 0; ntries < 100; ntries ++) {
- + if ( !(rt2860_io_mac_read(sc, RT2860_REG_BBP_CSR_CFG) &
- + RT2860_REG_BBP_CSR_BUSY) )
- + break;
- + DELAY(1);
- + }
- + if (ntries == 100) {
- + printf("%s:%s: BBP busy after 100 probes\n",
- + device_get_nameunit(sc->sc_dev), __func__);
- + return;
- + }
- + rt2860_io_mac_write(sc, RT2860_REG_BBP_CSR_CFG,
- + RT2860_REG_BBP_CSR_KICK | RT2860_REG_BBP_RW_MODE_PARALLEL |
- + (reg & RT2860_REG_BBP_REG_MASK) << RT2860_REG_BBP_REG_SHIFT |
- + (val & RT2860_REG_BBP_VAL_MASK) << RT2860_REG_BBP_VAL_SHIFT );
- + rt2860_io_bbp_read(sc, reg);
- + return;
- + }
- +
- + for (ntries = 0; ntries < 100; ntries++)
- + {
- + if (!(rt2860_io_mac_read(sc, RT2860_REG_H2M_MAILBOX_BBP_AGENT) &
- + RT2860_REG_BBP_CSR_BUSY))
- + break;
- +
- + DELAY(1);
- + }
- +
- + if (ntries == 100)
- + {
- + printf("%s: could not write to BBP through MCU: reg=0x%02x\n",
- + device_get_nameunit(sc->sc_dev), reg);
- + return;
- + }
- +
- + tmp = RT2860_REG_BBP_RW_MODE_PARALLEL |
- + RT2860_REG_BBP_CSR_BUSY |
- + ((reg & RT2860_REG_BBP_REG_MASK) << RT2860_REG_BBP_REG_SHIFT) |
- + ((val & RT2860_REG_BBP_VAL_MASK) << RT2860_REG_BBP_VAL_SHIFT);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX_BBP_AGENT, tmp);
- +
- + rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_BBP,
- + RT2860_REG_H2M_TOKEN_NO_INTR, 0);
- +
- + DELAY(1000);
- + }
- +
- + /*
- + * rt2860_io_rf_write
- + */
- + void rt2860_io_rf_write(struct rt2860_softc *sc, uint8_t reg, uint32_t val)
- + {
- + int ntries;
- + if (sc->mac_rev == 0x28720200)
- + {
- + for (ntries = 0; ntries < 100; ntries ++) {
- + if ( !(rt2860_io_mac_read(sc, RT2872_REG_RF_CSR_CFG) &
- + RT2872_REG_RF_CSR_BUSY) )
- + break;
- + DELAY(1);
- + }
- + if (ntries == 100) {
- + printf("%s:%s: RF busy after 100 probes\n",
- + device_get_nameunit(sc->sc_dev), __func__);
- + return;
- + }
- + rt2860_io_mac_write(sc, RT2872_REG_RF_CSR_CFG,
- + RT2872_REG_RF_CSR_KICK | RT2872_REG_RF_CSR_WRITE |
- + (reg & RT2872_REG_RF_ID_MASK) << RT2872_REG_RF_ID_SHIFT |
- + (val & RT2872_REG_RF_VAL_MASK) << RT2872_REG_RF_VAL_SHIFT );
- + rt2860_io_rf_read(sc, reg);
- + return;
- + }
- +
- +
- + for (ntries = 0; ntries < 100; ntries++)
- + if (!(rt2860_io_mac_read(sc, RT2860_REG_RF_CSR_CFG0) &
- + RT2860_REG_RF_BUSY))
- + break;
- +
- + if (ntries == 100)
- + {
- + printf("%s: could not write to RF: reg=0x%02x\n",
- + device_get_nameunit(sc->sc_dev), reg);
- + return;
- + }
- +
- + rt2860_io_mac_write(sc, RT2860_REG_RF_CSR_CFG0, val);
- + }
- +
- + /*
- + * rt2860_io_rf_read
- + */
- + int32_t rt2860_io_rf_read(struct rt2860_softc *sc, uint8_t reg)
- + {
- + int ntries;
- + if (sc->mac_rev == 0x28720200)
- + {
- + for (ntries = 0; ntries < 100; ntries ++) {
- + if ( !(rt2860_io_mac_read(sc, RT2872_REG_RF_CSR_CFG) &
- + RT2872_REG_RF_CSR_BUSY) )
- + break;
- + DELAY(1);
- + }
- + if (ntries == 100) {
- + printf("%s:%s: RF busy after 100 probes\n",
- + device_get_nameunit(sc->sc_dev), __func__);
- + return (-1);
- + }
- + rt2860_io_mac_write(sc, RT2872_REG_RF_CSR_CFG,
- + RT2872_REG_RF_CSR_KICK |
- + (reg & RT2872_REG_RF_ID_MASK) << RT2872_REG_RF_ID_SHIFT );
- +
- + for (ntries = 0; ntries < 100; ntries ++) {
- + if ( !(rt2860_io_mac_read(sc, RT2872_REG_RF_CSR_CFG) &
- + RT2872_REG_RF_CSR_BUSY) )
- + break;
- + DELAY(1);
- + }
- + if (ntries == 100) {
- + printf("%s:%s: RF busy after 100 probes\n",
- + device_get_nameunit(sc->sc_dev), __func__);
- + }
- +
- + return (rt2860_io_mac_read(sc, RT2872_REG_RF_CSR_CFG) & RT2872_REG_RF_VAL_MASK);
- + }
- + return (-1);
- + }
- +
- + /*
- + * rt2860_io_rf_load_defaults
- + */
- + void rt2860_io_rf_load_defaults(struct rt2860_softc *sc)
- + {
- + int i;
- +
- + if (sc->mac_rev == 0x28720200) {
- + for (i = 0; i < 32; i ++)
- + rt2860_io_rf_write(sc, i, rt3052_rf_default[i]);
- + }
- + }
- +
- + /*
- + * rt2860_io_mcu_cmd
- + */
- + void rt2860_io_mcu_cmd(struct rt2860_softc *sc, uint8_t cmd,
- + uint8_t token, uint16_t arg)
- + {
- + uint32_t tmp;
- + int ntries;
- +
- + if (sc->mac_rev == 0x28720200)
- + return;
- +
- + for (ntries = 0; ntries < 100; ntries++)
- + {
- + if (!(rt2860_io_mac_read(sc, RT2860_REG_H2M_MAILBOX) &
- + RT2860_REG_H2M_BUSY))
- + break;
- +
- + DELAY(2);
- + }
- +
- + if (ntries == 100)
- + {
- + printf("%s: could not read H2M: cmd=0x%02x\n",
- + device_get_nameunit(sc->sc_dev), cmd);
- + return;
- + }
- +
- + tmp = RT2860_REG_H2M_BUSY | (token << 16) | arg;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX, tmp);
- + rt2860_io_mac_write(sc, RT2860_REG_H2M_HOST_CMD, cmd);
- + }
- +
- + /*
- + * rt2860_io_mcu_cmd_check
- + */
- + int rt2860_io_mcu_cmd_check(struct rt2860_softc *sc, uint8_t cid)
- + {
- + uint32_t tmp, mask, status;
- + int result, ntries;
- +
- + result = -1;
- +
- + for (ntries = 0; ntries < 200; ntries++)
- + {
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_H2M_MAILBOX_CID);
- +
- + if (((cid >> RT2860_REG_H2M_CID0_SHIFT) & RT2860_REG_H2M_CID_MASK) == cid)
- + {
- + mask = (RT2860_REG_H2M_CID_MASK << RT2860_REG_H2M_CID0_SHIFT);
- + break;
- + }
- + else if (((tmp >> RT2860_REG_H2M_CID1_SHIFT) & RT2860_REG_H2M_CID_MASK) == cid)
- + {
- + mask = (RT2860_REG_H2M_CID_MASK << RT2860_REG_H2M_CID1_SHIFT);
- + break;
- + }
- + else if (((tmp >> RT2860_REG_H2M_CID2_SHIFT) & RT2860_REG_H2M_CID_MASK) == cid)
- + {
- + mask = (RT2860_REG_H2M_CID_MASK << RT2860_REG_H2M_CID2_SHIFT);
- + break;
- + }
- + else if (((tmp >> RT2860_REG_H2M_CID3_SHIFT) & RT2860_REG_H2M_CID_MASK) == cid)
- + {
- + mask = (RT2860_REG_H2M_CID_MASK << RT2860_REG_H2M_CID3_SHIFT);
- + break;
- + }
- +
- + DELAY(100);
- + }
- +
- + status = rt2860_io_mac_read(sc, RT2860_REG_H2M_MAILBOX_STATUS);
- +
- + if (ntries < 200)
- + {
- + status &= mask;
- +
- + if ((status == 0x1) ||
- + (status == 0x100) ||
- + (status == 0x10000) ||
- + (status == 0x1000000))
- + result = 0;
- + }
- +
- + rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX_STATUS, 0xffffffff);
- + rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX_CID, 0xffffffff);
- +
- + return result;
- + }
- +
- + /*
- + * rt2860_io_mcu_load_ucode
- + */
- + int rt2860_io_mcu_load_ucode(struct rt2860_softc *sc,
- + const uint8_t *ucode, size_t len)
- + {
- + int i, ntries;
- + uint16_t crc;
- +
- + for (i = 0, crc = 0xffff; i < len - 2; i++)
- + crc = RT2860_IO_BYTE_CRC16(rt2860_io_byte_rev(ucode[i]), crc);
- +
- + if (ucode[len - 2] != rt2860_io_byte_rev(crc >> 8) ||
- + ucode[len - 1] != rt2860_io_byte_rev(crc))
- + {
- + printf("%s: wrong microcode crc\n",
- + device_get_nameunit(sc->sc_dev));
- + return EINVAL;
- + }
- +
- + rt2860_io_mac_write(sc, RT2860_REG_PBF_SYS_CTRL, RT2860_REG_HST_PM_SEL);
- +
- + for(i = 0; i < len; i += 4)
- + {
- + rt2860_io_mac_write(sc, RT2860_REG_MCU_UCODE_BASE + i,
- + (ucode[i+3] << 24) | (ucode[i+2] << 16) |
- + (ucode[i+1] << 8) | ucode[i]);
- + }
- +
- + if (sc->mac_rev != 0x28720200)
- + rt2860_io_mac_write_multi(sc, RT2860_REG_MCU_UCODE_BASE,
- + ucode, len);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_PBF_SYS_CTRL, 0);
- +
- + if (sc->mac_rev != 0x28720200)
- + rt2860_io_mac_write(sc, RT2860_REG_PBF_SYS_CTRL,
- + RT2860_REG_MCU_RESET);
- +
- + DELAY(10000);
- +
- + /* initialize BBP R/W access agent */
- +
- + rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX_BBP_AGENT, 0);
- + rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX, 0);
- +
- + if (sc->mac_rev != 0x28720200) {
- +
- + for (ntries = 0; ntries < 1000; ntries++)
- + {
- + if (rt2860_io_mac_read(sc, RT2860_REG_PBF_SYS_CTRL) &
- + RT2860_REG_MCU_READY)
- + break;
- +
- + DELAY(1000);
- + }
- +
- + if (ntries == 1000)
- + {
- + printf("%s: timeout waiting for MCU to initialize\n",
- + device_get_nameunit(sc->sc_dev));
- + return ETIMEDOUT;
- + }
- + }
- +
- + return 0;
- + }
- +
- + /*
- + * rt2860_io_eeprom_shiftout_bits
- + */
- + static void rt2860_io_eeprom_shiftout_bits(struct rt2860_softc *sc,
- + uint16_t val, uint16_t count)
- + {
- + uint32_t mask, tmp;
- +
- + mask = (1 << (count - 1));
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR);
- +
- + tmp &= ~(RT2860_REG_EEDO | RT2860_REG_EEDI);
- +
- + do
- + {
- + tmp &= ~RT2860_REG_EEDI;
- +
- + if(val & mask)
- + tmp |= RT2860_REG_EEDI;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_EEPROM_CSR, tmp);
- +
- + RT2860_IO_EEPROM_RAISE_CLK(sc, tmp);
- + RT2860_IO_EEPROM_LOWER_CLK(sc, tmp);
- +
- + mask = (mask >> 1);
- + } while (mask);
- +
- + tmp &= ~RT2860_REG_EEDI;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_EEPROM_CSR, tmp);
- + }
- +
- + /*
- + * rt2860_io_eeprom_shiftin_bits
- + */
- + static uint16_t rt2860_io_eeprom_shiftin_bits(struct rt2860_softc *sc)
- + {
- + uint32_t tmp;
- + uint16_t val;
- + int i;
- +
- + val = 0;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR);
- +
- + tmp &= ~(RT2860_REG_EEDO | RT2860_REG_EEDI);
- +
- + for(i = 0; i < 16; i++)
- + {
- + val = (val << 1);
- +
- + RT2860_IO_EEPROM_RAISE_CLK(sc, tmp);
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR);
- +
- + RT2860_IO_EEPROM_LOWER_CLK(sc, tmp);
- +
- + tmp &= ~RT2860_REG_EEDI;
- + if(tmp & RT2860_REG_EEDO)
- + val |= 1;
- + }
- +
- + return val;
- + }
- +
- + /*
- + * rt2860_io_byte_rev
- + */
- + static uint8_t rt2860_io_byte_rev(uint8_t byte)
- + {
- + int i;
- + uint8_t tmp;
- +
- + for(i = 0, tmp = 0; ; i++)
- + {
- + if(byte & 0x80)
- + tmp |= 0x80;
- +
- + if(i == 7)
- + break;
- +
- + byte <<= 1;
- + tmp >>= 1;
- + }
- +
- + return tmp;
- + }
- +
- + /*
- + * rt2860_read_eeprom
- + */
- + void rt2860_read_eeprom(struct rt2860_softc *sc)
- + {
- + uint32_t tmp;
- + uint16_t val;
- + int i;
- +
- + /* read EEPROM address number */
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR);
- +
- + if((tmp & 0x30) == 0)
- + sc->eeprom_addr_num = 6;
- + else if((tmp & 0x30) == 0x10)
- + sc->eeprom_addr_num = 8;
- + else
- + sc->eeprom_addr_num = 8;
- +
- + /* read EEPROM version */
- +
- + sc->eeprom_rev = rt2860_io_eeprom_read(sc, RT2860_EEPROM_VERSION);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM rev=0x%04x\n",
- + device_get_nameunit(sc->sc_dev), sc->eeprom_rev);
- +
- + /* read MAC address */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_ADDRESS01);
- +
- + sc->mac_addr[0] = (val & 0xff);
- + sc->mac_addr[1] = (val >> 8);
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_ADDRESS23);
- +
- + sc->mac_addr[2] = (val & 0xff);
- + sc->mac_addr[3] = (val >> 8);
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_ADDRESS45);
- +
- + sc->mac_addr[4] = (val & 0xff);
- + sc->mac_addr[5] = (val >> 8);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM mac address=%s\n",
- + device_get_nameunit(sc->sc_dev), ether_sprintf(sc->mac_addr));
- +
- + /* read RF information */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_ANTENNA);
- + if (val == 0xffff)
- + {
- + printf("%s: invalid EEPROM antenna info\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->rf_rev = RT2860_EEPROM_RF_2820;
- + sc->ntxpath = 1;
- + sc->nrxpath = 2;
- + }
- + else
- + {
- + sc->rf_rev = (val >> 8) & 0xf;
- + sc->ntxpath = (val >> 4) & 0xf;
- + sc->nrxpath = (val & 0xf);
- + }
- +
- + if ((sc->mac_rev != 0x28830300) && (sc->nrxpath > 2))
- + {
- + /* only 2 Rx streams for RT2860 series */
- +
- + sc->nrxpath = 2;
- + }
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM RF rev=0x%04x, paths=%dT%dR\n",
- + device_get_nameunit(sc->sc_dev), sc->rf_rev, sc->ntxpath, sc->nrxpath);
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_NIC_CONFIG);
- + if ((val & 0xff00) != 0xff00)
- + sc->patch_dac = (val >> 15) & 1;
- +
- + sc->hw_radio_cntl = ((val & RT2860_EEPROM_HW_RADIO_CNTL) ? 1 : 0);
- + sc->tx_agc_cntl = ((val & RT2860_EEPROM_TX_AGC_CNTL) ? 1 : 0);
- + sc->ext_lna_2ghz = ((val & RT2860_EEPROM_EXT_LNA_2GHZ) ? 1 : 0);
- + sc->ext_lna_5ghz = ((val & RT2860_EEPROM_EXT_LNA_5GHZ) ? 1 : 0);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM NIC config: HW radio cntl=%d, Tx AGC cntl=%d, ext LNA gains=%d/%d\n",
- + device_get_nameunit(sc->sc_dev),
- + sc->hw_radio_cntl, sc->tx_agc_cntl, sc->ext_lna_2ghz, sc->ext_lna_5ghz);
- +
- + /* read country code */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_COUNTRY);
- +
- + sc->country_2ghz = (val >> 8) & 0xff;
- + sc->country_5ghz = (val & 0xff);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM country code=%d/%d\n",
- + device_get_nameunit(sc->sc_dev), sc->country_2ghz, sc->country_5ghz);
- +
- + /* read RF frequency offset */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RF_FREQ_OFF);
- +
- + if ((val & 0xff) != 0xff)
- + {
- + sc->rf_freq_off = (val & 0xff);
- + }
- + else
- + {
- + printf("%s: invalid EEPROM RF freq offset\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->rf_freq_off = 0;
- + }
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM freq offset=0x%02x\n",
- + device_get_nameunit(sc->sc_dev), sc->rf_freq_off);
- +
- + /* read LEDs operating mode */
- +
- + if (((val >> 8) & 0xff) != 0xff)
- + {
- + sc->led_cntl = ((val >> 8) & 0xff);
- + sc->led_off[0] = rt2860_io_eeprom_read(sc, RT2860_EEPROM_LED1_OFF);
- + sc->led_off[1] = rt2860_io_eeprom_read(sc, RT2860_EEPROM_LED2_OFF);
- + sc->led_off[2] = rt2860_io_eeprom_read(sc, RT2860_EEPROM_LED3_OFF);
- + }
- + else
- + {
- + printf("%s: invalid EEPROM LED settings\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->led_cntl = RT2860_EEPROM_LED_CNTL_DEFAULT;
- + sc->led_off[0] = RT2860_EEPROM_LED1_OFF_DEFAULT;
- + sc->led_off[1] = RT2860_EEPROM_LED2_OFF_DEFAULT;
- + sc->led_off[2] = RT2860_EEPROM_LED3_OFF_DEFAULT;
- + }
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM LED cntl=0x%02x, LEDs=0x%04x/0x%04x/0x%04x\n",
- + device_get_nameunit(sc->sc_dev), sc->led_cntl,
- + sc->led_off[0], sc->led_off[1], sc->led_off[2]);
- +
- + /* read RSSI offsets and LNA gains */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_LNA_GAIN);
- + if ((sc->mac_rev & 0xffff0000) >= 0x30710000)
- + sc->lna_gain[0] = RT3090_DEF_LNA;
- + else /* channel group 0 */
- + sc->lna_gain[0] = val & 0xff;
- +
- + sc->lna_gain[1] = (val >> 8) & 0xff;
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RSSI_OFF_2GHZ_BASE);
- +
- + sc->rssi_off_2ghz[0] = (val & 0xff);
- + sc->rssi_off_2ghz[1] = (val >> 8) & 0xff;
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RSSI_OFF_2GHZ_BASE + 2);
- +
- + if ((sc->mac_rev & 0xffff0000) >= 0x30710000) {
- + /*
- + * On RT3090 chips (limited to 2 Rx chains), this ROM
- + * field contains the Tx mixer gain for the 2GHz band.
- + */
- + if ((val & 0xff) != 0xff)
- + sc->txmixgain_2ghz = val & 0x7;
- + } else
- + sc->rssi_off_2ghz[2] = val & 0xff; /* Ant C */
- + sc->lna_gain[2] = (val >> 8) & 0xff;
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RSSI_OFF_5GHZ_BASE);
- +
- + sc->rssi_off_5ghz[0] = (val & 0xff);
- + sc->rssi_off_5ghz[1] = (val >> 8) & 0xff;
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RSSI_OFF_5GHZ_BASE + 2);
- +
- + sc->rssi_off_5ghz[2] = (val & 0xff);
- + sc->lna_gain[3] = (val >> 8) & 0xff;
- +
- + for (i = 2; i < RT2860_SOFTC_LNA_GAIN_COUNT; i++)
- + {
- + if (sc->lna_gain[i] == 0x00 || sc->lna_gain[i] == (int8_t) 0xff)
- + {
- + printf("%s: invalid EEPROM LNA gain #%d: 0x%02x\n",
- + device_get_nameunit(sc->sc_dev), i, sc->lna_gain[i]);
- +
- + sc->lna_gain[i] = sc->lna_gain[1];
- + }
- + }
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM LNA gains=0x%02x/0x%02x/0x%02x/0x%02x\n",
- + device_get_nameunit(sc->sc_dev),
- + sc->lna_gain[0], sc->lna_gain[1], sc->lna_gain[2], sc->lna_gain[3]);
- +
- + for (i = 0; i < RT2860_SOFTC_RSSI_OFF_COUNT; i++)
- + {
- + if (sc->rssi_off_2ghz[i] < RT2860_EEPROM_RSSI_OFF_MIN ||
- + sc->rssi_off_2ghz[i] > RT2860_EEPROM_RSSI_OFF_MAX)
- + {
- + printf("%s: invalid EEPROM RSSI offset #%d (2GHz): 0x%02x\n",
- + device_get_nameunit(sc->sc_dev), i, sc->rssi_off_2ghz[i]);
- +
- + sc->rssi_off_2ghz[i] = 0;
- + }
- +
- + if (sc->rssi_off_5ghz[i] < RT2860_EEPROM_RSSI_OFF_MIN ||
- + sc->rssi_off_5ghz[i] > RT2860_EEPROM_RSSI_OFF_MAX)
- + {
- + printf("%s: invalid EEPROM RSSI offset #%d (5GHz): 0x%02x\n",
- + device_get_nameunit(sc->sc_dev), i, sc->rssi_off_5ghz[i]);
- +
- + sc->rssi_off_5ghz[i] = 0;
- + }
- + }
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM RSSI offsets 2GHz=%d/%d/%d\n",
- + device_get_nameunit(sc->sc_dev),
- + sc->rssi_off_2ghz[0], sc->rssi_off_2ghz[1], sc->rssi_off_2ghz[2]);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM RSSI offsets 5GHz=%d/%d/%d\n",
- + device_get_nameunit(sc->sc_dev),
- + sc->rssi_off_5ghz[0], sc->rssi_off_5ghz[1], sc->rssi_off_5ghz[2]);
- +
- + /* read Tx power settings for 2GHz channels */
- +
- + for (i = 0; i < 14; i += 2)
- + {
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW1_2GHZ_BASE + i / 2);
- +
- + sc->txpow1[i + 0] = (int8_t) (val & 0xff);
- + sc->txpow1[i + 1] = (int8_t) (val >> 8);
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW2_2GHZ_BASE + i / 2);
- +
- + sc->txpow2[i + 0] = (int8_t) (val & 0xff);
- + sc->txpow2[i + 1] = (int8_t) (val >> 8);
- + }
- +
- + /* read Tx power settings for 5GHz channels */
- +
- + for (; i < RT2860_SOFTC_TXPOW_COUNT; i += 2)
- + {
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW1_5GHZ_BASE + i / 2);
- +
- + sc->txpow1[i + 0] = (int8_t) (val & 0xff);
- + sc->txpow1[i + 1] = (int8_t) (val >> 8);
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW2_5GHZ_BASE + i / 2);
- +
- + sc->txpow2[i + 0] = (int8_t) (val & 0xff);
- + sc->txpow2[i + 1] = (int8_t) (val >> 8);
- + }
- +
- + /* fix broken Tx power settings */
- +
- + for (i = 0; i < 14; i++)
- + {
- + if (sc->txpow1[i] < RT2860_EEPROM_TXPOW_2GHZ_MIN ||
- + sc->txpow1[i] > RT2860_EEPROM_TXPOW_2GHZ_MAX)
- + {
- + printf("%s: invalid EEPROM Tx power1 #%d (2GHz): 0x%02x\n",
- + device_get_nameunit(sc->sc_dev), i, sc->txpow1[i]);
- +
- + sc->txpow1[i] = RT2860_EEPROM_TXPOW_2GHZ_DEFAULT;
- + }
- +
- + if (sc->txpow2[i] < RT2860_EEPROM_TXPOW_2GHZ_MIN ||
- + sc->txpow2[i] > RT2860_EEPROM_TXPOW_2GHZ_MAX)
- + {
- + printf("%s: invalid EEPROM Tx power2 #%d (2GHz): 0x%02x\n",
- + device_get_nameunit(sc->sc_dev), i, sc->txpow2[i]);
- +
- + sc->txpow2[i] = RT2860_EEPROM_TXPOW_2GHZ_DEFAULT;
- + }
- + }
- +
- + for (; i < RT2860_SOFTC_TXPOW_COUNT; i++)
- + {
- + if (sc->txpow1[i] < RT2860_EEPROM_TXPOW_5GHZ_MIN ||
- + sc->txpow1[i] > RT2860_EEPROM_TXPOW_5GHZ_MAX)
- + {
- + printf("%s: invalid EEPROM Tx power1 #%d (5GHz): 0x%02x\n",
- + device_get_nameunit(sc->sc_dev), i, sc->txpow1[i]);
- +
- + sc->txpow1[i] = RT2860_EEPROM_TXPOW_5GHZ_DEFAULT;
- + }
- +
- + if (sc->txpow2[i] < RT2860_EEPROM_TXPOW_5GHZ_MIN ||
- + sc->txpow2[i] > RT2860_EEPROM_TXPOW_5GHZ_MAX)
- + {
- + printf("%s: invalid EEPROM Tx power2 #%d (5GHz): 0x%02x\n",
- + device_get_nameunit(sc->sc_dev), i, sc->txpow2[i]);
- +
- + sc->txpow2[i] = RT2860_EEPROM_TXPOW_5GHZ_DEFAULT;
- + }
- + }
- +
- + /* read Tx power per rate deltas */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW_RATE_DELTA);
- +
- + sc->txpow_rate_delta_2ghz = 0;
- + sc->txpow_rate_delta_5ghz = 0;
- +
- + if ((val & 0xff) != 0xff)
- + {
- + if (val & 0x80)
- + sc->txpow_rate_delta_2ghz = (val & 0xf);
- +
- + if (!(val & 0x40))
- + sc->txpow_rate_delta_2ghz = -sc->txpow_rate_delta_2ghz;
- + }
- +
- + val >>= 8;
- +
- + if ((val & 0xff) != 0xff)
- + {
- + if (val & 0x80)
- + sc->txpow_rate_delta_5ghz = (val & 0xf);
- +
- + if (!(val & 0x40))
- + sc->txpow_rate_delta_5ghz = -sc->txpow_rate_delta_5ghz;
- + }
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM Tx power per rate deltas=%d(2MHz), %d(5MHz)\n",
- + device_get_nameunit(sc->sc_dev),
- + sc->txpow_rate_delta_2ghz, sc->txpow_rate_delta_5ghz);
- +
- + /* read Tx power per rate */
- +
- + for (i = 0; i < RT2860_SOFTC_TXPOW_RATE_COUNT; i++)
- + {
- + rt2860_io_eeprom_read_multi(sc, RT2860_EEPROM_TXPOW_RATE_BASE + i * sizeof(uint32_t),
- + &tmp, sizeof(uint32_t));
- +
- + sc->txpow_rate_20mhz[i] = tmp;
- + sc->txpow_rate_40mhz_2ghz[i] =
- + rt2860_read_eeprom_txpow_rate_add_delta(tmp, sc->txpow_rate_delta_2ghz);
- + sc->txpow_rate_40mhz_5ghz[i] =
- + rt2860_read_eeprom_txpow_rate_add_delta(tmp, sc->txpow_rate_delta_5ghz);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM Tx power per rate #%d=0x%08x(20MHz), 0x%08x(40MHz/2GHz), 0x%08x(40MHz/5GHz)\n",
- + device_get_nameunit(sc->sc_dev), i,
- + sc->txpow_rate_20mhz[i], sc->txpow_rate_40mhz_2ghz[i], sc->txpow_rate_40mhz_5ghz[i]);
- + }
- +
- + if (sc->tx_agc_cntl)
- + sc->tx_agc_cntl_2ghz = sc->tx_agc_cntl_5ghz = 1;
- +
- + /* read factory-calibrated samples for temperature compensation */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE);
- +
- + sc->tssi_2ghz[0] = (val & 0xff); /* [-4] */
- + sc->tssi_2ghz[1] = (val >> 8); /* [-3] */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE + 2);
- +
- + sc->tssi_2ghz[2] = (val & 0xff); /* [-2] */
- + sc->tssi_2ghz[3] = (val >> 8); /* [-1] */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE + 2 * 2);
- +
- + sc->tssi_2ghz[4] = (val & 0xff); /* [0] */
- + sc->tssi_2ghz[5] = (val >> 8); /* [+1] */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE + 3 * 2);
- +
- + sc->tssi_2ghz[6] = (val & 0xff); /* [+2] */
- + sc->tssi_2ghz[7] = (val >> 8); /* [+3] */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE + 4 * 2);
- +
- + sc->tssi_2ghz[8] = (val & 0xff); /* [+4] */
- + sc->tssi_step_2ghz = (val >> 8);
- +
- + if (sc->tssi_2ghz[4] == 0xff)
- + sc->tx_agc_cntl_2ghz = 0;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM TSSI 2GHz: 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, "
- + "0x%02x, 0x%02x, step=%d\n",
- + device_get_nameunit(sc->sc_dev),
- + sc->tssi_2ghz[0], sc->tssi_2ghz[1], sc->tssi_2ghz[2],
- + sc->tssi_2ghz[3], sc->tssi_2ghz[4], sc->tssi_2ghz[5],
- + sc->tssi_2ghz[6], sc->tssi_2ghz[7], sc->tssi_2ghz[8],
- + sc->tssi_step_2ghz);
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE);
- +
- + sc->tssi_5ghz[0] = (val & 0xff); /* [-4] */
- + sc->tssi_5ghz[1] = (val >> 8); /* [-3] */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE + 2);
- +
- + sc->tssi_5ghz[2] = (val & 0xff); /* [-2] */
- + sc->tssi_5ghz[3] = (val >> 8); /* [-1] */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE + 2 * 2);
- +
- + sc->tssi_5ghz[4] = (val & 0xff); /* [0] */
- + sc->tssi_5ghz[5] = (val >> 8); /* [+1] */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE + 3 * 2);
- +
- + sc->tssi_5ghz[6] = (val & 0xff); /* [+2] */
- + sc->tssi_5ghz[7] = (val >> 8); /* [+3] */
- +
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE + 4 * 2);
- +
- + sc->tssi_5ghz[8] = (val & 0xff); /* [+4] */
- + sc->tssi_step_5ghz = (val >> 8);
- +
- + if (sc->tssi_5ghz[4] == 0xff)
- + sc->tx_agc_cntl_5ghz = 0;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM TSSI 5GHz: 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, "
- + "0x%02x, 0x%02x, step=%d\n",
- + device_get_nameunit(sc->sc_dev),
- + sc->tssi_5ghz[0], sc->tssi_5ghz[1], sc->tssi_5ghz[2],
- + sc->tssi_5ghz[3], sc->tssi_5ghz[4], sc->tssi_5ghz[5],
- + sc->tssi_5ghz[6], sc->tssi_5ghz[7], sc->tssi_5ghz[8],
- + sc->tssi_step_5ghz);
- +
- + /* read default BBP settings */
- +
- + rt2860_io_eeprom_read_multi(sc, RT2860_EEPROM_BBP_BASE,
- + sc->bbp_eeprom, RT2860_SOFTC_BBP_EEPROM_COUNT * 2);
- +
- + if ((sc->mac_rev & 0xffff0000) >= 0x30710000) {
- + /* read vendor RF settings */
- + rt2860_io_eeprom_read_multi(sc, RT3071_EEPROM_RF_BASE, sc->rf, 10 * 2);
- + }
- +
- + /* read powersave level */
- + val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_POWERSAVE_LEVEL);
- +
- + sc->powersave_level = val & 0xff;
- +
- + if ((sc->powersave_level & 0xff) == 0xff)
- + printf("%s: invalid EEPROM powersave level\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
- + "%s: EEPROM powersave level=0x%02x\n",
- + device_get_nameunit(sc->sc_dev), sc->powersave_level);
- + }
- +
- + /*
- + * rt2860_read_eeprom_txpow_rate_add_delta
- + */
- + uint32_t rt2860_read_eeprom_txpow_rate_add_delta(uint32_t txpow_rate,
- + int8_t delta)
- + {
- + int8_t b4;
- + int i;
- +
- + for (i = 0; i < 8; i++)
- + {
- + b4 = txpow_rate & 0xf;
- + b4 += delta;
- +
- + if (b4 < 0)
- + b4 = 0;
- + else if (b4 > 0xf)
- + b4 = 0xf;
- +
- + txpow_rate = (txpow_rate >> 4) | (b4 << 28);
- + }
- +
- + return txpow_rate;
- + }
- +
- + /*
- + * LED functions NOTE/FIXME: Untested by me
- + */
- +
- + /*
- + * rt2860_led_brightness
- + */
- + void rt2860_led_brightness(struct rt2860_softc *sc, uint8_t brightness)
- + {
- + uint8_t polarity;
- + uint16_t tmp;
- +
- + polarity = (sc->led_cntl & RT2860_EEPROM_LED_POLARITY) ? 1 : 0;
- +
- + tmp = (polarity << 8) | brightness;
- +
- + rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_LED_BRIGHTNESS,
- + RT2860_REG_H2M_TOKEN_NO_INTR, tmp);
- + }
- +
- + /*
- + * rt2860_led_cmd
- + */
- + void rt2860_led_cmd(struct rt2860_softc *sc, uint8_t cmd)
- + {
- + uint16_t tmp;
- +
- + tmp = (cmd << 8) | (sc->led_cntl & RT2860_EEPROM_LED_MODE_MASK);
- +
- + rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_LEDS,
- + RT2860_REG_H2M_TOKEN_NO_INTR, tmp);
- + }
- +
- + /*
- + * RF MAC functions
- + */
- +
- +
- + uint8_t
- + rt3090_rf_read(struct rt2860_softc *sc, uint8_t reg)
- + {
- + uint32_t tmp;
- + int ntries;
- +
- + for (ntries = 0; ntries < 100; ntries++) {
- + if (!(rt2860_io_mac_read(sc, RT3070_RF_CSR_CFG) & RT3070_RF_KICK))
- + break;
- + DELAY(1);
- + }
- + if (ntries == 100) {
- + device_printf(sc->sc_dev, "could not read RF register\n");
- + return 0xff;
- + }
- + tmp = RT3070_RF_KICK | reg << 8;
- + rt2860_io_mac_write(sc, RT3070_RF_CSR_CFG, tmp);
- +
- + for (ntries = 0; ntries < 100; ntries++) {
- + tmp = rt2860_io_mac_read(sc, RT3070_RF_CSR_CFG);
- + if (!(tmp & RT3070_RF_KICK))
- + break;
- + DELAY(1);
- + }
- + if (ntries == 100) {
- + device_printf(sc->sc_dev, "could not read RF register\n");
- + return 0xff;
- + }
- + return tmp & 0xff;
- + }
- +
- + void
- + rt3090_rf_write(struct rt2860_softc *sc, uint8_t reg, uint8_t val)
- + {
- + uint32_t tmp;
- + int ntries;
- +
- + for (ntries = 0; ntries < 10; ntries++) {
- + if (!(rt2860_io_mac_read(sc, RT3070_RF_CSR_CFG) & RT3070_RF_KICK))
- + break;
- + DELAY(10);
- + }
- + if (ntries == 10) {
- + device_printf(sc->sc_dev, "could not write to RF\n");
- + return;
- + }
- +
- + tmp = RT3070_RF_WRITE | RT3070_RF_KICK | reg << 8 | val;
- + rt2860_io_mac_write(sc, RT3070_RF_CSR_CFG, tmp);
- + }
- +
- + /*
- + * rt2860_rf_name
- + */
- + const char *rt2860_rf_name(int rf_rev)
- + {
- + switch (rf_rev)
- + {
- + case RT2860_EEPROM_RF_2820:
- + return "RT2820 2.4G 2T3R";
- +
- + case RT2860_EEPROM_RF_2850:
- + return "RT2850 2.4G/5G 2T3R";
- +
- + case RT2860_EEPROM_RF_2720:
- + return "RT2720 2.4G 1T2R";
- +
- + case RT2860_EEPROM_RF_2750:
- + return "RT2750 2.4G/5G 1T2R";
- +
- + case RT2860_EEPROM_RF_3020:
- + return "RT3020 2.4G 1T1R";
- +
- + case RT2860_EEPROM_RF_2020:
- + return "RT2020 2.4G B/G";
- +
- + case RT2860_EEPROM_RF_3021:
- + return "RT3021 2.4G 1T2R";
- +
- + case RT2860_EEPROM_RF_3022:
- + return "RT3022 2.4G 2T2R";
- +
- + case RT2860_EEPROM_RF_3052:
- + return "RT3052 2.4G/5G 2T2R";
- +
- + case RT2860_EEPROM_RF_2853:
- + return "RT2853 2.4G.5G 3T3R";
- +
- + case RT2860_EEPROM_RF_3320:
- + return "RT3320 2.4G 1T1R with PA";
- +
- + case RT2860_EEPROM_RF_3322:
- + return "RT3322 2.4G 2T2R with PA";
- +
- + case RT2860_EEPROM_RF_3053:
- + return "RT3053 2.4G/5G 3T3R";
- +
- + default:
- + return "unknown";
- + }
- + }
- +
- + /*
- + * rt2860_rf_select_chan_group
- + */
- + void rt2860_rf_select_chan_group(struct rt2860_softc *sc,
- + struct ieee80211_channel *c)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + int chan, group;
- + uint32_t tmp;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- +
- + chan = ieee80211_chan2ieee(ic, c);
- + if (chan == 0 || chan == IEEE80211_CHAN_ANY)
- + return;
- +
- + if (chan <= 14)
- + group = 0;
- + else if (chan <= 64)
- + group = 1;
- + else if (chan <= 128)
- + group = 2;
- + else
- + group = 3;
- +
- + rt2860_io_bbp_write(sc, 62, 0x37 - sc->lna_gain[group]);
- + rt2860_io_bbp_write(sc, 63, 0x37 - sc->lna_gain[group]);
- + rt2860_io_bbp_write(sc, 64, 0x37 - sc->lna_gain[group]);
- + rt2860_io_bbp_write(sc, 86, 0x00);
- +
- + if (group == 0)
- + {
- + if (sc->ext_lna_2ghz)
- + {
- + rt2860_io_bbp_write(sc, 82, 0x62);
- + rt2860_io_bbp_write(sc, 75, 0x46);
- + }
- + else
- + {
- + rt2860_io_bbp_write(sc, 82, 0x84);
- + rt2860_io_bbp_write(sc, 75, 0x50);
- + }
- + }
- + else
- + {
- + rt2860_io_bbp_write(sc, 82, 0xf2);
- +
- + if (sc->ext_lna_5ghz)
- + rt2860_io_bbp_write(sc, 75, 0x46);
- + else
- + rt2860_io_bbp_write(sc, 75, 0x50);
- + }
- +
- + if (group == 0)
- + {
- + tmp = 0x2e + sc->lna_gain[group];
- + }
- + else
- + {
- + if ((ic->ic_flags & IEEE80211_F_SCAN) || !IEEE80211_IS_CHAN_HT40(c))
- + tmp = 0x32 + sc->lna_gain[group] * 5 / 3;
- + else
- + tmp = 0x3a + sc->lna_gain[group] * 5 / 3;
- + }
- +
- + rt2860_io_bbp_write(sc, 66, tmp);
- +
- + tmp = RT2860_REG_RFTR_ENABLE |
- + RT2860_REG_TRSW_ENABLE |
- + RT2860_REG_LNA_PE_G1_ENABLE |
- + RT2860_REG_LNA_PE_A1_ENABLE |
- + RT2860_REG_LNA_PE_G0_ENABLE |
- + RT2860_REG_LNA_PE_A0_ENABLE;
- +
- + if (group == 0)
- + tmp |= RT2860_REG_PA_PE_G1_ENABLE |
- + RT2860_REG_PA_PE_G0_ENABLE;
- + else
- + tmp |= RT2860_REG_PA_PE_A1_ENABLE |
- + RT2860_REG_PA_PE_A0_ENABLE;
- +
- + if (sc->ntxpath == 1)
- + tmp &= ~(RT2860_REG_PA_PE_G1_ENABLE | RT2860_REG_PA_PE_A1_ENABLE);
- +
- + if (sc->nrxpath == 1)
- + tmp &= ~(RT2860_REG_LNA_PE_G1_ENABLE | RT2860_REG_LNA_PE_A1_ENABLE);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_TX_PIN_CFG, tmp);
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_TX_BAND_CFG);
- +
- + tmp &= ~(RT2860_REG_TX_BAND_BG | RT2860_REG_TX_BAND_A | RT2860_REG_TX_BAND_HT40_ABOVE);
- +
- + if (group == 0)
- + tmp |= RT2860_REG_TX_BAND_BG;
- + else
- + tmp |= RT2860_REG_TX_BAND_A;
- +
- + /* set central channel position */
- +
- + if (IEEE80211_IS_CHAN_HT40U(c))
- + tmp |= RT2860_REG_TX_BAND_HT40_BELOW;
- + else if (IEEE80211_IS_CHAN_HT40D(c))
- + tmp |= RT2860_REG_TX_BAND_HT40_ABOVE;
- + else
- + tmp |= RT2860_REG_TX_BAND_HT40_BELOW;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_TX_BAND_CFG, tmp);
- +
- + /* set bandwidth (20MHz or 40MHz) */
- +
- + tmp = rt2860_io_bbp_read(sc, 4);
- +
- + tmp &= ~0x18;
- +
- + if (IEEE80211_IS_CHAN_HT40(c))
- + tmp |= 0x10;
- +
- + rt2860_io_bbp_write(sc, 4, tmp);
- +
- + /* set central channel position */
- +
- + tmp = rt2860_io_bbp_read(sc, 3);
- +
- + tmp &= ~0x20;
- +
- + if (IEEE80211_IS_CHAN_HT40D(c))
- + tmp |= 0x20;
- +
- + rt2860_io_bbp_write(sc, 3, tmp);
- +
- + if (sc->mac_rev == 0x28600100)
- + {
- + if (!IEEE80211_IS_CHAN_HT40(c))
- + {
- + rt2860_io_bbp_write(sc, 69, 0x16);
- + rt2860_io_bbp_write(sc, 70, 0x08);
- + rt2860_io_bbp_write(sc, 73, 0x12);
- + }
- + else
- + {
- + rt2860_io_bbp_write(sc, 69, 0x1a);
- + rt2860_io_bbp_write(sc, 70, 0x0a);
- + rt2860_io_bbp_write(sc, 73, 0x16);
- + }
- + }
- +
- + }
- +
- + void
- + rt3090_set_chan(struct rt2860_softc *sc, u_int chan)
- + {
- + int8_t txpow1, txpow2;
- + uint8_t rf;
- + int i;
- +
- + KASSERT((chan >= 1 && chan <= 14), "RT3090 is 2GHz only"); /* RT3090 is 2GHz only */
- +
- + /* find the settings for this channel (we know it exists) */
- + for (i = 0; rt2860_rf2850[i].chan != chan; i++);
- +
- + /* use Tx power values from EEPROM */
- + txpow1 = sc->txpow1[i];
- + txpow2 = sc->txpow2[i];
- +
- + rt3090_rf_write(sc, 2, rt3090_freqs[i].n);
- + rf = rt3090_rf_read(sc, 3);
- + rf = (rf & ~0x0f) | rt3090_freqs[i].k;
- + rt3090_rf_write(sc, 3, rf);
- + rf = rt3090_rf_read(sc, 6);
- + rf = (rf & ~0x03) | rt3090_freqs[i].r;
- + rt3090_rf_write(sc, 6, rf);
- +
- + /* set Tx0 power */
- + rf = rt3090_rf_read(sc, 12);
- + rf = (rf & ~0x1f) | txpow1;
- + rt3090_rf_write(sc, 12, rf);
- +
- + /* set Tx1 power */
- + rf = rt3090_rf_read(sc, 13);
- + rf = (rf & ~0x1f) | txpow2;
- + rt3090_rf_write(sc, 13, rf);
- +
- + rf = rt3090_rf_read(sc, 1);
- + rf &= ~0xfc;
- + if (sc->ntxpath == 1)
- + rf |= RT3070_TX1_PD | RT3070_TX2_PD;
- + else if (sc->ntxpath == 2)
- + rf |= RT3070_TX2_PD;
- + if (sc->nrxpath == 1)
- + rf |= RT3070_RX1_PD | RT3070_RX2_PD;
- + else if (sc->nrxpath == 2)
- + rf |= RT3070_RX2_PD;
- + rt3090_rf_write(sc, 1, rf);
- +
- + /* set RF offset */
- + rf = rt3090_rf_read(sc, 23);
- + rf = (rf & ~0x7f) | sc->rf_freq_off;
- + rt3090_rf_write(sc, 23, rf);
- +
- + /* program RF filter */
- + rf = rt3090_rf_read(sc, 24); /* Tx */
- + rf = (rf & ~0x3f) | sc->rf24_20mhz;
- + rt3090_rf_write(sc, 24, rf);
- + rf = rt3090_rf_read(sc, 31); /* Rx */
- + rf = (rf & ~0x3f) | sc->rf24_20mhz;
- + rt3090_rf_write(sc, 31, rf);
- +
- + /* enable RF tuning */
- + rf = rt3090_rf_read(sc, 7);
- + rt3090_rf_write(sc, 7, rf | RT3070_TUNE);
- + }
- +
- + int
- + rt3090_rf_init(struct rt2860_softc *sc)
- + {
- + uint32_t tmp;
- + uint8_t rf, bbp;
- + int i;
- +
- + rf = rt3090_rf_read(sc, 30);
- + /* toggle RF R30 bit 7 */
- + rt3090_rf_write(sc, 30, rf | 0x80);
- + DELAY(1000);
- + rt3090_rf_write(sc, 30, rf & ~0x80);
- +
- + tmp = rt2860_io_mac_read(sc, RT3070_LDO_CFG0);
- + tmp &= ~0x1f000000;
- + if (sc->patch_dac && (sc->mac_rev & 0x0000ffff) < 0x0211)
- + tmp |= 0x0d000000; /* 1.35V */
- + else
- + tmp |= 0x01000000; /* 1.2V */
- + rt2860_io_mac_write(sc, RT3070_LDO_CFG0, tmp);
- +
- + /* patch LNA_PE_G1 */
- + tmp = rt2860_io_mac_read(sc, RT3070_GPIO_SWITCH);
- + rt2860_io_mac_write(sc, RT3070_GPIO_SWITCH, tmp & ~0x20);
- +
- + /* initialize RF registers to default value */
- + for (i = 0; i < (sizeof(rt3090_def_rf)/2); i++) {
- + rt3090_rf_write(sc, rt3090_def_rf[i].reg,
- + rt3090_def_rf[i].val);
- + }
- +
- + /* select 20MHz bandwidth */
- + rt3090_rf_write(sc, 31, 0x14);
- +
- + rf = rt3090_rf_read(sc, 6);
- + rt3090_rf_write(sc, 6, rf | 0x40);
- +
- + if ((sc->mac_rev & 0xffff0000) != 0x35930000) {
- + /* calibrate filter for 20MHz bandwidth */
- + sc->rf24_20mhz = 0x1f; /* default value */
- + rt3090_filter_calib(sc, 0x07, 0x16, &sc->rf24_20mhz);
- +
- + /* select 40MHz bandwidth */
- + bbp = rt2860_io_bbp_read(sc, 4);
- + rt2860_io_bbp_write(sc, 4, (bbp & ~0x08) | 0x10);
- + rf = rt3090_rf_read(sc, 31);
- + rt3090_rf_write(sc, 31, rf | 0x20);
- +
- + /* calibrate filter for 40MHz bandwidth */
- + sc->rf24_40mhz = 0x2f; /* default value */
- + rt3090_filter_calib(sc, 0x27, 0x19, &sc->rf24_40mhz);
- +
- + /* go back to 20MHz bandwidth */
- + bbp = rt2860_io_bbp_read(sc, 4);
- + rt2860_io_bbp_write(sc, 4, bbp & ~0x18);
- + }
- + if ((sc->mac_rev & 0x0000ffff) < 0x0211)
- + rt3090_rf_write(sc, 27, 0x03);
- +
- + tmp = rt2860_io_mac_read(sc, RT3070_OPT_14);
- + rt2860_io_mac_write(sc, RT3070_OPT_14, tmp | 1);
- +
- + if (sc->rf_rev == RT2860_EEPROM_RF_3020)
- + rt3090_set_rx_antenna(sc, 0);
- +
- + bbp = rt2860_io_bbp_read(sc, 138);
- + if ((sc->mac_rev & 0xffff0000) == 0x35930000) {
- + if (sc->ntxpath == 1)
- + bbp |= 0x60; /* turn off DAC1 and DAC2 */
- + else if (sc->ntxpath == 2)
- + bbp |= 0x40; /* turn off DAC2 */
- + if (sc->nrxpath == 1)
- + bbp &= ~0x06; /* turn off ADC1 and ADC2 */
- + else if (sc->nrxpath == 2)
- + bbp &= ~0x04; /* turn off ADC2 */
- + } else {
- + if (sc->ntxpath == 1)
- + bbp |= 0x20; /* turn off DAC1 */
- + if (sc->nrxpath == 1)
- + bbp &= ~0x02; /* turn off ADC1 */
- + }
- + rt2860_io_bbp_write(sc, 138, bbp);
- +
- + rf = rt3090_rf_read(sc, 1);
- + rf &= ~(RT3070_RX0_PD | RT3070_TX0_PD);
- + rf |= RT3070_RF_BLOCK | RT3070_RX1_PD | RT3070_TX1_PD;
- + rt3090_rf_write(sc, 1, rf);
- +
- + rf = rt3090_rf_read(sc, 15);
- + rt3090_rf_write(sc, 15, rf & ~RT3070_TX_LO2);
- +
- + rf = rt3090_rf_read(sc, 17);
- + rf &= ~RT3070_TX_LO1;
- + if ((sc->mac_rev & 0x0000ffff) >= 0x0211 && !sc->ext_lna_2ghz)
- + rf |= 0x20; /* fix for long range Rx issue */
- + if (sc->txmixgain_2ghz >= 2)
- + rf = (rf & ~0x7) | sc->txmixgain_2ghz;
- + rt3090_rf_write(sc, 17, rf);
- +
- + rf = rt3090_rf_read(sc, 20);
- + rt3090_rf_write(sc, 20, rf & ~RT3070_RX_LO1);
- +
- + rf = rt3090_rf_read(sc, 21);
- + rt3090_rf_write(sc, 21, rf & ~RT3070_RX_LO2);
- +
- + return 0;
- + }
- +
- + void
- + rt3090_set_rx_antenna(struct rt2860_softc *sc, int aux)
- + {
- + uint32_t tmp;
- +
- + if (aux) {
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR);
- + rt2860_io_mac_write(sc, RT2860_REG_EEPROM_CSR, tmp & ~RT2860_REG_EESK);
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_GPIO_CTRL_CFG);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_GPIO_CTRL_CFG, (tmp & ~0x0808) | 0x08);
- + } else {
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR);
- + rt2860_io_mac_write(sc, RT2860_REG_EEPROM_CSR, tmp | RT2860_REG_EESK);
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_GPIO_CTRL_CFG);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_GPIO_CTRL_CFG, tmp & ~0x0808);
- + }
- + }
- +
- + void
- + rt3090_rf_wakeup(struct rt2860_softc *sc)
- + {
- + uint32_t tmp;
- + uint8_t rf;
- +
- + if ((sc->mac_rev & 0xffff0000) == 0x35930000) {
- + /* enable VCO */
- + rf = rt3090_rf_read(sc, 1);
- + rt3090_rf_write(sc, 1, rf | RT3593_VCO);
- +
- + /* initiate VCO calibration */
- + rf = rt3090_rf_read(sc, 3);
- + rt3090_rf_write(sc, 3, rf | RT3593_VCOCAL);
- +
- + /* enable VCO bias current control */
- + rf = rt3090_rf_read(sc, 6);
- + rt3090_rf_write(sc, 6, rf | RT3593_VCO_IC);
- +
- + /* initiate res calibration */
- + rf = rt3090_rf_read(sc, 2);
- + rt3090_rf_write(sc, 2, rf | RT3593_RESCAL);
- +
- + /* set reference current control to 0.33 mA */
- + rf = rt3090_rf_read(sc, 22);
- + rf &= ~RT3593_CP_IC_MASK;
- + rf |= 1 << RT3593_CP_IC_SHIFT;
- + rt3090_rf_write(sc, 22, rf);
- +
- + /* enable RX CTB */
- + rf = rt3090_rf_read(sc, 46);
- + rt3090_rf_write(sc, 46, rf | RT3593_RX_CTB);
- +
- + rf = rt3090_rf_read(sc, 20);
- + rf &= ~(RT3593_LDO_RF_VC_MASK | RT3593_LDO_PLL_VC_MASK);
- + rt3090_rf_write(sc, 20, rf);
- + } else {
- + /* enable RF block */
- + rf = rt3090_rf_read(sc, 1);
- + rt3090_rf_write(sc, 1, rf | RT3070_RF_BLOCK);
- +
- + /* enable VCO bias current control */
- + rf = rt3090_rf_read(sc, 7);
- + rt3090_rf_write(sc, 7, rf | 0x30);
- +
- + rf = rt3090_rf_read(sc, 9);
- + rt3090_rf_write(sc, 9, rf | 0x0e);
- +
- + /* enable RX CTB */
- + rf = rt3090_rf_read(sc, 21);
- + rt3090_rf_write(sc, 21, rf | RT3070_RX_CTB);
- +
- + /* fix Tx to Rx IQ glitch by raising RF voltage */
- + rf = rt3090_rf_read(sc, 27);
- + rf &= ~0x77;
- + if ((sc->mac_rev & 0x0000ffff) < 0x0211)
- + rf |= 0x03;
- + rt3090_rf_write(sc, 27, rf);
- + }
- + if (sc->patch_dac && (sc->mac_rev & 0x0000ffff) < 0x0211) {
- + tmp = rt2860_io_mac_read(sc, RT3070_LDO_CFG0);
- + tmp = (tmp & ~0x1f000000) | 0x0d000000;
- + rt2860_io_mac_write(sc, RT3070_LDO_CFG0, tmp);
- + }
- + }
- +
- + int
- + rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target,
- + uint8_t *val)
- + {
- + uint8_t rf22, rf24;
- + uint8_t bbp55_pb, bbp55_sb, delta;
- + int ntries;
- +
- + /* program filter */
- + rf24 = rt3090_rf_read(sc, 24);
- + rf24 = (rf24 & 0xc0) | init; /* initial filter value */
- + rt3090_rf_write(sc, 24, rf24);
- +
- + /* enable baseband loopback mode */
- + rf22 = rt3090_rf_read(sc, 22);
- + rt3090_rf_write(sc, 22, rf22 | RT3070_BB_LOOPBACK);
- +
- + /* set power and frequency of passband test tone */
- + rt2860_io_bbp_write(sc, 24, 0x00);
- + for (ntries = 0; ntries < 100; ntries++) {
- + /* transmit test tone */
- + rt2860_io_bbp_write(sc, 25, 0x90);
- + DELAY(1000);
- + /* read received power */
- + bbp55_pb = rt2860_io_bbp_read(sc, 55);
- + if (bbp55_pb != 0)
- + break;
- + }
- + if (ntries == 100)
- + return ETIMEDOUT;
- +
- + /* set power and frequency of stopband test tone */
- + rt2860_io_bbp_write(sc, 24, 0x06);
- + for (ntries = 0; ntries < 100; ntries++) {
- + /* transmit test tone */
- + rt2860_io_bbp_write(sc, 25, 0x90);
- + DELAY(1000);
- + /* read received power */
- + bbp55_sb = rt2860_io_bbp_read(sc, 55);
- +
- + delta = bbp55_pb - bbp55_sb;
- + if (delta > target)
- + break;
- +
- + /* reprogram filter */
- + rf24++;
- + rt3090_rf_write(sc, 24, rf24);
- + }
- + if (ntries < 100) {
- + if (rf24 != init)
- + rf24--; /* backtrack */
- + *val = rf24;
- + rt3090_rf_write(sc, 24, rf24);
- + }
- +
- + /* restore initial state */
- + rt2860_io_bbp_write(sc, 24, 0x00);
- +
- + /* disable baseband loopback mode */
- + rf22 = rt3090_rf_read(sc, 22);
- + rt3090_rf_write(sc, 22, rf22 & ~RT3070_BB_LOOPBACK);
- +
- + return 0;
- + }
- +
- + void
- + rt3090_rf_setup(struct rt2860_softc *sc)
- + {
- + uint8_t bbp;
- + int i;
- +
- + if ((sc->mac_rev & 0x0000ffff) >= 0x0211) {
- + /* enable DC filter */
- + rt2860_io_bbp_write(sc, 103, 0xc0);
- +
- + /* improve power consumption */
- + bbp = rt2860_io_bbp_read(sc, 31);
- + rt2860_io_bbp_write(sc, 31, bbp & ~0x03);
- + }
- +
- + rt2860_io_mac_write(sc, RT2860_REG_TX_SW_CFG1, 0);
- + if ((sc->mac_rev & 0x0000ffff) < 0x0211) {
- + rt2860_io_mac_write(sc, RT2860_REG_TX_SW_CFG2,
- + sc->patch_dac ? 0x2c : 0x0f);
- + } else
- + rt2860_io_mac_write(sc, RT2860_REG_TX_SW_CFG2, 0);
- +
- + /* initialize RF registers from ROM */
- + for (i = 0; i < 10; i++) {
- + if (sc->rf[i].reg == 0 || sc->rf[i].reg == 0xff)
- + continue;
- + rt3090_rf_write(sc, sc->rf[i].reg, sc->rf[i].val);
- + }
- + }
- +
- +
- + /*
- + * rt2860_rf_set_chan
- + */
- + void rt2860_rf_set_chan(struct rt2860_softc *sc,
- + struct ieee80211_channel *c)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + const struct rt2860_rf_prog *prog;
- + uint32_t r1, r2, r3, r4;
- + int8_t txpow1, txpow2;
- + int i, chan;
- +
- + if (sc->mac_rev == 0x28720200) {
- + rt2872_rf_set_chan(sc, c);
- + return;
- + }
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- + prog = rt2860_rf_2850;
- +
- + /* get central channel position */
- +
- + chan = ieee80211_chan2ieee(ic, c);
- +
- + if ((sc->mac_rev & 0xffff0000) >= 0x30710000) {
- + rt3090_set_chan(sc, chan);
- + return;
- + }
- +
- + if (IEEE80211_IS_CHAN_HT40U(c))
- + chan += 2;
- + else if (IEEE80211_IS_CHAN_HT40D(c))
- + chan -= 2;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_CHAN,
- + "%s: RF set channel: channel=%u, HT%s%s\n",
- + device_get_nameunit(sc->sc_dev),
- + ieee80211_chan2ieee(ic, c),
- + !IEEE80211_IS_CHAN_HT(c) ? " disabled" :
- + IEEE80211_IS_CHAN_HT20(c) ? "20":
- + IEEE80211_IS_CHAN_HT40U(c) ? "40U" : "40D",
- + (ic->ic_flags & IEEE80211_F_SCAN) ? ", scanning" : "");
- +
- + if (chan == 0 || chan == IEEE80211_CHAN_ANY)
- + return;
- +
- + for (i = 0; prog[i].chan != chan; i++);
- +
- + r1 = prog[i].r1;
- + r2 = prog[i].r2;
- + r3 = prog[i].r3;
- + r4 = prog[i].r4;
- +
- + txpow1 = sc->txpow1[i];
- + txpow2 = sc->txpow2[i];
- +
- + if (sc->ntxpath == 1)
- + r2 |= (1 << 14);
- +
- + if (sc->nrxpath == 2)
- + r2 |= (1 << 6);
- + else if (sc->nrxpath == 1)
- + r2 |= (1 << 17) | (1 << 6);
- +
- + if (IEEE80211_IS_CHAN_2GHZ(c))
- + {
- + r3 = (r3 & 0xffffc1ff) | (txpow1 << 9);
- + r4 = (r4 & ~0x001f87c0) | (sc->rf_freq_off << 15) |
- + (txpow2 << 6);
- + }
- + else
- + {
- + r3 = r3 & 0xffffc1ff;
- + r4 = (r4 & ~0x001f87c0) | (sc->rf_freq_off << 15);
- +
- + if (txpow1 >= RT2860_EEPROM_TXPOW_5GHZ_MIN && txpow1 < 0)
- + {
- + txpow1 = (-RT2860_EEPROM_TXPOW_5GHZ_MIN + txpow1);
- + if (txpow1 > RT2860_EEPROM_TXPOW_5GHZ_MAX)
- + txpow1 = RT2860_EEPROM_TXPOW_5GHZ_MAX;
- +
- + r3 |= (txpow1 << 10);
- + }
- + else
- + {
- + if (txpow1 > RT2860_EEPROM_TXPOW_5GHZ_MAX)
- + txpow1 = RT2860_EEPROM_TXPOW_5GHZ_MAX;
- +
- + r3 |= (txpow1 << 10) | (1 << 9);
- + }
- +
- + if (txpow2 >= RT2860_EEPROM_TXPOW_5GHZ_MIN && txpow2 < 0)
- + {
- + txpow2 = (-RT2860_EEPROM_TXPOW_5GHZ_MIN + txpow2);
- + if (txpow2 > RT2860_EEPROM_TXPOW_5GHZ_MAX)
- + txpow2 = RT2860_EEPROM_TXPOW_5GHZ_MAX;
- +
- + r4 |= (txpow2 << 7);
- + }
- + else
- + {
- + if (txpow2 > RT2860_EEPROM_TXPOW_5GHZ_MAX)
- + txpow2 = RT2860_EEPROM_TXPOW_5GHZ_MAX;
- +
- + r4 |= (txpow2 << 7) | (1 << 6);
- + }
- + }
- +
- + if (!(ic->ic_flags & IEEE80211_F_SCAN) && IEEE80211_IS_CHAN_HT40(c))
- + r4 |= (1 << 21);
- +
- + rt2860_io_rf_write(sc, RT2860_REG_RF_R1, r1);
- + rt2860_io_rf_write(sc, RT2860_REG_RF_R2, r2);
- + rt2860_io_rf_write(sc, RT2860_REG_RF_R3, r3 & ~(1 << 2));
- + rt2860_io_rf_write(sc, RT2860_REG_RF_R4, r4);
- +
- + DELAY(200);
- +
- + rt2860_io_rf_write(sc, RT2860_REG_RF_R1, r1);
- + rt2860_io_rf_write(sc, RT2860_REG_RF_R2, r2);
- + rt2860_io_rf_write(sc, RT2860_REG_RF_R3, r3 | (1 << 2));
- + rt2860_io_rf_write(sc, RT2860_REG_RF_R4, r4);
- +
- + DELAY(200);
- +
- + rt2860_io_rf_write(sc, RT2860_REG_RF_R1, r1);
- + rt2860_io_rf_write(sc, RT2860_REG_RF_R2, r2);
- + rt2860_io_rf_write(sc, RT2860_REG_RF_R3, r3 & ~(1 << 2));
- + rt2860_io_rf_write(sc, RT2860_REG_RF_R4, r4);
- +
- + rt2860_rf_select_chan_group(sc, c);
- +
- + DELAY(1000);
- + }
- +
- + /*
- + * rt2872_rf_set_chan
- + */
- + static void
- + rt2872_rf_set_chan(struct rt2860_softc *sc,
- + struct ieee80211_channel *c)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + const struct rt2860_rf_prog *prog;
- + uint32_t r1, r2, r3, r4;
- + uint32_t r6, r7, r12, r13, r23, r24;
- + int8_t txpow1, txpow2;
- + int i, chan;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- + prog = rt2860_rf_2850;
- +
- + /* get central channel position */
- +
- + chan = ieee80211_chan2ieee(ic, c);
- +
- + if (IEEE80211_IS_CHAN_HT40U(c))
- + chan += 2;
- + else if (IEEE80211_IS_CHAN_HT40D(c))
- + chan -= 2;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_CHAN,
- + "%s: RF set channel: channel=%u, HT%s%s\n",
- + device_get_nameunit(sc->sc_dev),
- + ieee80211_chan2ieee(ic, c),
- + !IEEE80211_IS_CHAN_HT(c) ? " disabled" :
- + IEEE80211_IS_CHAN_HT20(c) ? "20":
- + IEEE80211_IS_CHAN_HT40U(c) ? "40U" : "40D",
- + (ic->ic_flags & IEEE80211_F_SCAN) ? ", scanning" : "");
- +
- + if (chan == 0 || chan == IEEE80211_CHAN_ANY)
- + return;
- +
- + for (i = 0; prog[i].chan != chan; i++);
- +
- + r1 = prog[i].r1;
- + r2 = prog[i].r2;
- + r3 = prog[i].r3;
- + r4 = prog[i].r4;
- +
- + txpow1 = sc->txpow1[i];
- + txpow2 = sc->txpow2[i];
- +
- + for (i = 0; rt2860_rf_fi3020[i].channel != chan; i++);
- +
- + /* Programm channel parameters */
- + r2 = rt2860_rf_fi3020[i].n;
- + rt2860_io_rf_write(sc, 2 , r2 );
- + r3 = rt2860_rf_fi3020[i].k;
- + rt2860_io_rf_write(sc, 3 , r3 );
- +
- + r6 = (rt3052_rf_default[6] & 0xFC) | (rt2860_rf_fi3020[i].r & 0x03);
- + rt2860_io_rf_write(sc, 6 , r6 );
- +
- + /* Set Tx Power */
- + r12 = (rt3052_rf_default[12] & 0xE0) | (txpow1 & 0x1f);
- + rt2860_io_rf_write(sc, 12, r12);
- +
- + /* Set Tx1 Power */
- + r13 = (rt3052_rf_default[13] & 0xE0) | (txpow2 & 0x1f);
- + rt2860_io_rf_write(sc, 13, r13);
- +
- + /* Set RF offset */
- + r23 = (rt3052_rf_default[23] & 0x80) | (sc->rf_freq_off);
- + rt2860_io_rf_write(sc, 23, r23);
- +
- + /* Set BW */
- + r24 = (rt3052_rf_default[24] & 0xDF);
- + if (!(ic->ic_flags & IEEE80211_F_SCAN) && IEEE80211_IS_CHAN_HT40(c))
- + r24 |= 0x20;
- + rt2860_io_rf_write(sc, 24, r24);
- +
- + /* Enable RF tuning */
- + r7 = (rt3052_rf_default[7]) | 1;
- + rt2860_io_rf_write(sc, 7 , r7 );
- +
- + /* Antenna */
- + r1 = (rt3052_rf_default[1] & 0xab) | ((sc->nrxpath == 1)?0x10:0) |
- + ((sc->ntxpath == 1)?0x20:0);
- + rt2860_io_rf_write(sc, 1 , r1 );
- +
- + DELAY(200);
- +
- + rt2860_rf_select_chan_group(sc, c);
- +
- + DELAY(1000);
- + }
- + /*
- + * AMRR functions
- + */
- +
- + /*
- + * rt2860_amrr_init
- + */
- + void rt2860_amrr_init(struct rt2860_amrr *amrr, struct ieee80211vap *vap,
- + int ntxpath, int min_success_threshold, int max_success_threshold, int msecs)
- + {
- + int t;
- +
- + amrr->ntxpath = ntxpath;
- +
- + amrr->min_success_threshold = min_success_threshold;
- + amrr->max_success_threshold = max_success_threshold;
- +
- + if (msecs < 100)
- + msecs = 100;
- +
- + t = msecs_to_ticks(msecs);
- +
- + amrr->interval = (t < 1) ? 1 : t;
- + }
- +
- + /*
- + * rt2860_amrr_cleanup
- + */
- + void rt2860_amrr_cleanup(struct rt2860_amrr *amrr)
- + {
- + }
- +
- + /*
- + * rt2860_amrr_node_init
- + */
- + void rt2860_amrr_node_init(struct rt2860_amrr *amrr,
- + struct rt2860_amrr_node *amrr_node, struct ieee80211_node *ni)
- + {
- + const struct ieee80211_rateset *rs;
- +
- + amrr_node->amrr = amrr;
- + amrr_node->success = 0;
- + amrr_node->recovery = 0;
- + amrr_node->txcnt = 0;
- + amrr_node->retrycnt = 0;
- + amrr_node->success_threshold = amrr->min_success_threshold;
- +
- + if (ni->ni_flags & IEEE80211_NODE_HT)
- + {
- + rs = (const struct ieee80211_rateset *) &ni->ni_htrates;
- +
- + for (amrr_node->rate_index = rs->rs_nrates - 1;
- + amrr_node->rate_index > 0 && (rs->rs_rates[amrr_node->rate_index] & IEEE80211_RATE_VAL) > 4;
- + amrr_node->rate_index--) ;
- +
- + ni->ni_txrate = rs->rs_rates[amrr_node->rate_index] | IEEE80211_RATE_MCS;
- + }
- + else
- + {
- + rs = &ni->ni_rates;
- +
- + for (amrr_node->rate_index = rs->rs_nrates - 1;
- + amrr_node->rate_index > 0 && (rs->rs_rates[amrr_node->rate_index] & IEEE80211_RATE_VAL) > 72;
- + amrr_node->rate_index--) ;
- +
- + ni->ni_txrate = rs->rs_rates[amrr_node->rate_index] & IEEE80211_RATE_VAL;
- + }
- +
- + amrr_node->ticks = ticks;
- + }
- +
- + /*
- + * rt2860_amrr_choose
- + */
- + int rt2860_amrr_choose(struct ieee80211_node *ni,
- + struct rt2860_amrr_node *amrr_node)
- + {
- + struct rt2860_amrr *amrr;
- + int rate_index;
- +
- + amrr = amrr_node->amrr;
- +
- + if (RT2860_AMRR_IS_ENOUGH(amrr_node) &&
- + (ticks - amrr_node->ticks) > amrr->interval)
- + {
- + rate_index = rt2860_amrr_update(amrr, amrr_node, ni);
- + if (rate_index != amrr_node->rate_index)
- + {
- + if (ni->ni_flags & IEEE80211_NODE_HT)
- + ni->ni_txrate = ni->ni_htrates.rs_rates[rate_index] | IEEE80211_RATE_MCS;
- + else
- + ni->ni_txrate = ni->ni_rates.rs_rates[rate_index] & IEEE80211_RATE_VAL;
- +
- + amrr_node->rate_index = rate_index;
- + }
- +
- + amrr_node->ticks = ticks;
- + }
- + else
- + {
- + rate_index = amrr_node->rate_index;
- + }
- +
- + return rate_index;
- + }
- +
- + /*
- + * rt2860_amrr_update
- + */
- +
- + static int rt2860_amrr_update(struct rt2860_amrr *amrr,
- + struct rt2860_amrr_node *amrr_node, struct ieee80211_node *ni)
- + {
- + const struct ieee80211_rateset *rs;
- + int rate_index;
- +
- + KASSERT(RT2860_AMRR_IS_ENOUGH(amrr_node),
- + ("not enough Tx count: txcnt=%d",
- + amrr_node->txcnt));
- +
- + if (ni->ni_flags & IEEE80211_NODE_HT)
- + rs = (const struct ieee80211_rateset *) &ni->ni_htrates;
- + else
- + rs = &ni->ni_rates;
- +
- + rate_index = amrr_node->rate_index;
- +
- + if (RT2860_AMRR_IS_SUCCESS(amrr_node))
- + {
- + amrr_node->success++;
- + if ((amrr_node->success >= amrr_node->success_threshold) &&
- + (rate_index + 1 < rs->rs_nrates) &&
- + (!(ni->ni_flags & IEEE80211_NODE_HT) || (rs->rs_rates[rate_index + 1] & IEEE80211_RATE_VAL) < (amrr->ntxpath * 8)))
- + {
- + amrr_node->recovery = 1;
- + amrr_node->success = 0;
- +
- + rate_index++;
- + }
- + else
- + {
- + amrr_node->recovery = 0;
- + }
- + }
- + else if (RT2860_AMRR_IS_FAILURE(amrr_node))
- + {
- + amrr_node->success = 0;
- +
- + if (rate_index > 0)
- + {
- + if (amrr_node->recovery)
- + {
- + amrr_node->success_threshold *= 2;
- + if (amrr_node->success_threshold > amrr->max_success_threshold)
- + amrr_node->success_threshold = amrr->max_success_threshold;
- + }
- + else
- + {
- + amrr_node->success_threshold = amrr->min_success_threshold;
- + }
- +
- + rate_index--;
- + }
- +
- + amrr_node->recovery = 0;
- + }
- +
- + amrr_node->txcnt = 0;
- + amrr_node->retrycnt = 0;
- +
- + return rate_index;
- + }
- +
- + /*
- + * rt2860_attach
- + */
- + int rt2860_attach(device_t dev, int id)
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + int error, ntries, i;
- +
- + sc = device_get_softc(dev);
- + sc->sc_id = id;
- + sc->sc_dev = dev;
- +
- + mtx_init(&sc->sc_mtx, device_get_nameunit(dev),
- + MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE);
- +
- + if (sc == NULL) /* Kludge verification begin */
- + {
- + printf("FIXME debug error...invalid softc! Ice cream melted.\n");
- + error = ENXIO;
- + goto fail;
- + } else {
- + if (sc->sc_st == 0)
- + {
- + printf("FIXME debug error...invalid bus tag! GET OFF THE BUS.\n");
- + error = ENXIO;
- + goto fail;
- + }
- + if (sc->sc_sh == 0)
- + {
- + printf("FIXME debug error...invalid handle! Drink something else!!\n");
- + error = ENXIO;
- + goto fail;
- + }
- + }
- +
- +
- + /* done already, I believe */
- + /*
- + sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
- + &sc->mem_rid, RF_ACTIVE);
- + if (sc->mem == NULL)
- + {
- + printf("%s: invalid memory resource\n",
- + device_get_nameunit(dev));
- + error = ENXIO;
- + goto fail;
- + }
- +
- + sc->sc_st = rman_get_bustag(sc->mem);
- + sc->sc_sh = rman_get_bushandle(sc->mem);
- +
- + sc->irq_rid = 0;
- + sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
- + &sc->irq_rid, RF_ACTIVE | RF_SHAREABLE);
- + */
- +
- + /*
- + if (sc->irq == NULL)
- + {
- + printf("%s: invalid IRQ resource\n",
- + device_get_nameunit(dev));
- + error = ENXIO;
- + goto fail;
- + }
- + */
- + sc->tx_stbc = rt2860_tx_stbc;
- +
- + #ifdef RT2860_DEBUG
- + sc->debug = rt2860_debug;
- +
- + SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
- + "debug", CTLFLAG_RW, &sc->debug, 0, "rt2860 debug level");
- + #endif
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_ANY,
- + "%s: attaching\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + /* wait for NIC to initialize */
- +
- + for (ntries = 0; ntries < 1000; ntries++)
- + {
- + sc->mac_rev = rt2860_io_mac_read(sc, RT2860_REG_MAC_CSR0);
- + if (sc->mac_rev != 0x00000000 && sc->mac_rev != 0xffffffff)
- + break;
- +
- + DELAY(10);
- + }
- +
- + if (ntries == 1000)
- + {
- + printf("%s: timeout waiting for NIC to initialize\n",
- + device_get_nameunit(dev));
- + error = EIO;
- + goto fail;
- + }
- +
- + rt2860_read_eeprom(sc);
- +
- + printf("%s: MAC/BBP RT2860 (rev 0x%08x), RF %s\n",
- + device_get_nameunit(sc->sc_dev), sc->mac_rev,
- + rt2860_rf_name(sc->rf_rev));
- +
- + /* clear key tables */
- +
- + rt2860_asic_clear_keytables(sc);
- +
- + /* allocate Tx and Rx rings */
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_COUNT; i++)
- + {
- + error = rt2860_alloc_tx_ring(sc, &sc->tx_ring[i], i);
- + if (error != 0)
- + {
- + printf("%s: could not allocate Tx ring #%d\n",
- + device_get_nameunit(sc->sc_dev), i);
- + goto fail;
- + }
- + }
- +
- + sc->tx_ring_mgtqid = 5;
- +
- + error = rt2860_alloc_rx_ring(sc, &sc->rx_ring);
- + if (error != 0)
- + {
- + printf("%s: could not allocate Rx ring\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + callout_init(&sc->periodic_ch, 0);
- + callout_init_mtx(&sc->tx_watchdog_ch, &sc->sc_mtx, 0);
- +
- + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- + if (ifp == NULL)
- + {
- + printf("%s: could not if_alloc()\n",
- + device_get_nameunit(sc->sc_dev));
- + error = ENOMEM;
- + goto fail;
- + }
- +
- + ifp->if_softc = sc;
- +
- + if_initname(ifp, device_get_name(dev), device_get_unit(sc->sc_dev));
- +
- + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- +
- + ifp->if_init = rt2860_init;
- + ifp->if_ioctl = rt2860_ioctl;
- + ifp->if_start = rt2860_start;
- +
- + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- + ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
- + IFQ_SET_READY(&ifp->if_snd);
- +
- + ic = ifp->if_l2com;
- +
- + ic->ic_ifp = ifp;
- +
- + ic->ic_phytype = IEEE80211_T_HT;
- + ic->ic_opmode = IEEE80211_M_STA;
- +
- + ic->ic_caps = IEEE80211_C_MONITOR |
- + IEEE80211_C_IBSS |
- + IEEE80211_C_STA |
- + IEEE80211_C_AHDEMO |
- + IEEE80211_C_HOSTAP |
- + IEEE80211_C_WDS |
- + IEEE80211_C_MBSS |
- + IEEE80211_C_BGSCAN |
- + IEEE80211_C_TXPMGT |
- + IEEE80211_C_SHPREAMBLE |
- + IEEE80211_C_SHSLOT |
- + IEEE80211_C_TXFRAG |
- + IEEE80211_C_BURST |
- + IEEE80211_C_WME |
- + IEEE80211_C_WPA;
- +
- + ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP |
- + IEEE80211_CRYPTO_TKIP |
- + IEEE80211_CRYPTO_TKIPMIC |
- + IEEE80211_CRYPTO_AES_CCM;
- +
- + ic->ic_htcaps = IEEE80211_HTC_HT |
- + IEEE80211_HTC_AMSDU | /* A-MSDU Tx */
- + IEEE80211_HTC_AMPDU | /* A-MPDU Tx */
- + IEEE80211_HTC_SMPS | /* MIMO power save */
- + IEEE80211_HTCAP_MAXAMSDU_3839 | /* max. A-MSDU Rx length */
- + IEEE80211_HTCAP_CHWIDTH40 | /* HT 40MHz channel width */
- + IEEE80211_HTCAP_GREENFIELD | /* HT greenfield */
- + IEEE80211_HTCAP_SHORTGI20 | /* HT 20MHz short GI */
- + IEEE80211_HTCAP_SHORTGI40 | /* HT 40MHz short GI */
- + IEEE80211_HTCAP_SMPS_OFF; /* MIMO power save disabled */
- +
- + /* spatial streams */
- +
- + if (sc->nrxpath == 2)
- + ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_2STREAM;
- + else if (sc->nrxpath == 3)
- + ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_3STREAM;
- + else
- + ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_1STREAM;
- +
- + if (sc->ntxpath > 1)
- + ic->ic_htcaps |= IEEE80211_HTCAP_TXSTBC;
- +
- + /* delayed BA */
- +
- + if (sc->mac_rev != 0x28600100)
- + ic->ic_htcaps |= IEEE80211_HTCAP_DELBA;
- +
- + /* init channels */
- +
- + ic->ic_nchans = 0;
- +
- + rt2860_init_channels(sc);
- +
- + rt2860_init_channels_ht40(sc);
- +
- + ieee80211_ifattach(ic, sc->mac_addr);
- +
- + ic->ic_vap_create = rt2860_vap_create;
- + ic->ic_vap_delete = rt2860_vap_delete;
- +
- + ic->ic_node_alloc = rt2860_node_alloc;
- +
- + sc->node_cleanup = ic->ic_node_cleanup;
- + ic->ic_node_cleanup = rt2860_node_cleanup;
- +
- + ic->ic_node_getmimoinfo = rt2860_node_getmimoinfo;
- + ic->ic_setregdomain = rt2860_setregdomain;
- + ic->ic_getradiocaps = rt2860_getradiocaps;
- + ic->ic_scan_start = rt2860_scan_start;
- + ic->ic_scan_end = rt2860_scan_end;
- + ic->ic_set_channel = rt2860_set_channel;
- + ic->ic_newassoc = rt2860_newassoc;
- + ic->ic_updateslot = rt2860_updateslot;
- + ic->ic_update_promisc = rt2860_update_promisc;
- + ic->ic_update_mcast = rt2860_update_mcast;
- + ic->ic_wme.wme_update = rt2860_wme_update;
- + ic->ic_raw_xmit = rt2860_raw_xmit;
- +
- + sc->recv_action = ic->ic_recv_action;
- + ic->ic_recv_action = rt2860_recv_action;
- +
- + sc->send_action = ic->ic_send_action;
- + ic->ic_send_action = rt2860_send_action;
- +
- + sc->addba_response = ic->ic_addba_response;
- + ic->ic_addba_response = rt2860_addba_response;
- +
- + sc->addba_stop = ic->ic_addba_stop;
- + ic->ic_addba_stop = rt2860_addba_stop;
- +
- + sc->ampdu_rx_start = ic->ic_ampdu_rx_start;
- + ic->ic_ampdu_rx_start = rt2860_ampdu_rx_start;
- +
- + sc->ampdu_rx_stop = ic->ic_ampdu_rx_stop;
- + ic->ic_ampdu_rx_stop = rt2860_ampdu_rx_stop;
- +
- + /* hardware requires padding between 802.11 frame header and body */
- +
- + ic->ic_flags |= IEEE80211_F_DATAPAD | IEEE80211_F_DOTH;
- +
- + ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;
- +
- + ieee80211_radiotap_attach(ic,
- + &sc->txtap.ihdr, sizeof(sc->txtap),
- + RT2860_SOFTC_TX_RADIOTAP_PRESENT,
- + &sc->rxtap.ihdr, sizeof(sc->rxtap),
- + RT2860_SOFTC_RX_RADIOTAP_PRESENT);
- +
- + /* init task queue */
- +
- + TASK_INIT(&sc->rx_done_task, 0, rt2860_rx_done_task, sc);
- + TASK_INIT(&sc->tx_done_task, 0, rt2860_tx_done_task, sc);
- + TASK_INIT(&sc->fifo_sta_full_task, 0, rt2860_fifo_sta_full_task, sc);
- + TASK_INIT(&sc->periodic_task, 0, rt2860_periodic_task, sc);
- +
- + sc->rx_process_limit = 100;
- +
- + sc->taskqueue = taskqueue_create("rt2860_taskq", M_NOWAIT,
- + taskqueue_thread_enqueue, &sc->taskqueue);
- +
- + taskqueue_start_threads(&sc->taskqueue, 1, PI_NET, "%s taskq",
- + device_get_nameunit(sc->sc_dev));
- +
- + rt2860_sysctl_attach(sc);
- +
- + if (bootverbose)
- + ieee80211_announce(ic);
- +
- + /* set up interrupt */
- + /* AGain, already handled
- + error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
- + NULL, rt2860_intr, sc, &sc->irqh);
- + if (error != 0)
- + {
- + printf("%s: could not set up interrupt\n",
- + device_get_nameunit(dev));
- + goto fail;
- + }
- + */
- + return 0;
- +
- + fail:
- +
- + /* free Tx and Rx rings */
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_COUNT; i++)
- + rt2860_free_tx_ring(sc, &sc->tx_ring[i]);
- +
- + rt2860_free_rx_ring(sc, &sc->rx_ring);
- +
- + mtx_destroy(&sc->sc_mtx);
- + /*
- + if (sc->mem != NULL)
- + bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
- +
- + if (sc->irq != NULL)
- + bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
- + */
- + return error;
- + }
- +
- + /*
- + * rt2860_detach
- + */
- + int rt2860_detach(void *xsc)
- + {
- + struct rt2860_softc *sc = xsc;
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + int i;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_ANY,
- + "ral2860 detach");
- +
- + RT2860_SOFTC_LOCK(sc);
- +
- + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
- +
- + callout_stop(&sc->periodic_ch);
- + callout_stop(&sc->tx_watchdog_ch);
- +
- + taskqueue_drain(sc->taskqueue, &sc->rx_done_task);
- + taskqueue_drain(sc->taskqueue, &sc->tx_done_task);
- + taskqueue_drain(sc->taskqueue, &sc->fifo_sta_full_task);
- + taskqueue_drain(sc->taskqueue, &sc->periodic_task);
- +
- + /* free Tx and Rx rings */
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_COUNT; i++)
- + rt2860_free_tx_ring(sc, &sc->tx_ring[i]);
- +
- + rt2860_free_rx_ring(sc, &sc->rx_ring);
- +
- + RT2860_SOFTC_UNLOCK(sc);
- +
- + ieee80211_ifdetach(ic);
- +
- + if_free(ifp);
- +
- + taskqueue_free(sc->taskqueue);
- +
- + mtx_destroy(&sc->sc_mtx);
- + /*
- + * Handled by RAL overlords
- + */
- + /*
- + bus_generic_detach(sc->sc_dev);
- +
- + bus_teardown_intr(sc->sc_dev, sc->irq, sc->irqh);
- +
- + bus_release_resource(sc->sc_dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
- +
- + bus_release_resource(sc->sc_dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
- + */
- + return 0;
- + }
- +
- + /*
- + * rt2860_shutdown
- + */
- + void rt2860_shutdown(void *xsc)
- + {
- + struct rt2860_softc *sc = xsc;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_ANY,
- + "%s: shutting down\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + rt2860_stop(sc);
- +
- + sc->flags &= ~RT2860_SOFTC_FLAGS_UCODE_LOADED;
- + }
- +
- + /*
- + * rt2860_suspend
- + */
- + void rt2860_suspend(void *xsc)
- + {
- + struct rt2860_softc *sc = xsc;
- +
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_ANY,
- + "%s: suspending\n",
- + device_get_nameunit(sc->sc_dev));
- +
- +
- + rt2860_stop(sc);
- +
- + sc->flags &= ~RT2860_SOFTC_FLAGS_UCODE_LOADED;
- + }
- +
- + /*
- + * rt2860_resume
- + */
- + void rt2860_resume(void *xsc)
- + {
- + struct rt2860_softc *sc = xsc;
- + struct ifnet *ifp;
- +
- + ifp = sc->sc_ifp;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_ANY,
- + "%s: resuming\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + if (ifp->if_flags & IFF_UP)
- + rt2860_init(sc);
- +
- + }
- +
- + /*
- + * rt2860_init_channels
- + */
- + static void rt2860_init_channels(struct rt2860_softc *sc)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + struct ieee80211_channel *c;
- + int i, flags;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- +
- + /* set supported channels for 2GHz band */
- +
- + for (i = 1; i <= 14; i++)
- + {
- + c = &ic->ic_channels[ic->ic_nchans++];
- + flags = IEEE80211_CHAN_B;
- +
- + c->ic_freq = ieee80211_ieee2mhz(i, flags);
- + c->ic_ieee = i;
- + c->ic_flags = flags;
- +
- + c = &ic->ic_channels[ic->ic_nchans++];
- + flags = IEEE80211_CHAN_B | IEEE80211_CHAN_HT20;
- +
- + c->ic_freq = ieee80211_ieee2mhz(i, flags);
- + c->ic_ieee = i;
- + c->ic_flags = flags;
- +
- + c = &ic->ic_channels[ic->ic_nchans++];
- + flags = IEEE80211_CHAN_G;
- +
- + c->ic_freq = ieee80211_ieee2mhz(i, flags);
- + c->ic_ieee = i;
- + c->ic_flags = flags;
- +
- + c = &ic->ic_channels[ic->ic_nchans++];
- + flags = IEEE80211_CHAN_G | IEEE80211_CHAN_HT20;
- +
- + c->ic_freq = ieee80211_ieee2mhz(i, flags);
- + c->ic_ieee = i;
- + c->ic_flags = flags;
- + }
- +
- + /* set supported channels for 5GHz band */
- +
- + if (sc->rf_rev == RT2860_EEPROM_RF_2850 ||
- + sc->rf_rev == RT2860_EEPROM_RF_2750 ||
- + sc->rf_rev == RT2860_EEPROM_RF_3052)
- + {
- + for (i = 36; i <= 64; i += 4)
- + {
- + c = &ic->ic_channels[ic->ic_nchans++];
- + flags = IEEE80211_CHAN_A;
- +
- + c->ic_freq = ieee80211_ieee2mhz(i, flags);
- + c->ic_ieee = i;
- + c->ic_flags = flags;
- +
- + c = &ic->ic_channels[ic->ic_nchans++];
- + flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
- +
- + c->ic_freq = ieee80211_ieee2mhz(i, flags);
- + c->ic_ieee = i;
- + c->ic_flags = flags;
- + }
- +
- + for (i = 100; i <= 140; i += 4)
- + {
- + c = &ic->ic_channels[ic->ic_nchans++];
- + flags = IEEE80211_CHAN_A;
- +
- + c->ic_freq = ieee80211_ieee2mhz(i, flags);
- + c->ic_ieee = i;
- + c->ic_flags = flags;
- +
- + c = &ic->ic_channels[ic->ic_nchans++];
- + flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
- +
- + c->ic_freq = ieee80211_ieee2mhz(i, flags);
- + c->ic_ieee = i;
- + c->ic_flags = flags;
- + }
- +
- + for (i = 149; i <= 165; i += 4)
- + {
- + c = &ic->ic_channels[ic->ic_nchans++];
- + flags = IEEE80211_CHAN_A;
- +
- + c->ic_freq = ieee80211_ieee2mhz(i, flags);
- + c->ic_ieee = i;
- + c->ic_flags = flags;
- +
- + c = &ic->ic_channels[ic->ic_nchans++];
- + flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
- +
- + c->ic_freq = ieee80211_ieee2mhz(i, flags);
- + c->ic_ieee = i;
- + c->ic_flags = flags;
- + }
- + }
- + }
- +
- + /*
- + * rt2860_init_channels_ht40
- + */
- + static void rt2860_init_channels_ht40(struct rt2860_softc *sc)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + struct ieee80211_channel *c, *cent, *ext;
- + int i, flags;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- +
- + /* set supported channels for 2GHz band */
- +
- + for (i = 1; i <= 14; i++)
- + {
- + flags = IEEE80211_CHAN_G | IEEE80211_CHAN_HT40;
- +
- + /* find the center channel */
- +
- + cent = ieee80211_find_channel_byieee(ic, i,
- + flags & ~IEEE80211_CHAN_HT);
- + if (cent == NULL)
- + {
- + printf("%s: skip channel %d, could not find center channel\n",
- + device_get_nameunit(sc->sc_dev), i);
- + continue;
- + }
- +
- + /* find the extension channel */
- +
- + ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
- + flags & ~IEEE80211_CHAN_HT);
- + if (ext == NULL)
- + {
- + printf("%s: skip channel %d, could not find extension channel\n",
- + device_get_nameunit(sc->sc_dev), i);
- + continue;
- + }
- +
- + c = &ic->ic_channels[ic->ic_nchans++];
- +
- + *c = *cent;
- + c->ic_extieee = ext->ic_ieee;
- + c->ic_flags &= ~IEEE80211_CHAN_HT;
- + c->ic_flags |= IEEE80211_CHAN_HT40U;
- +
- + c = &ic->ic_channels[ic->ic_nchans++];
- +
- + *c = *ext;
- + c->ic_extieee = cent->ic_ieee;
- + c->ic_flags &= ~IEEE80211_CHAN_HT;
- + c->ic_flags |= IEEE80211_CHAN_HT40D;
- + }
- +
- + /* set supported channels for 5GHz band */
- +
- + if (sc->rf_rev == RT2860_EEPROM_RF_2850 ||
- + sc->rf_rev == RT2860_EEPROM_RF_2750 ||
- + sc->rf_rev == RT2860_EEPROM_RF_3052)
- + {
- + for (i = 36; i <= 64; i += 4)
- + {
- + flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
- +
- + /* find the center channel */
- +
- + cent = ieee80211_find_channel_byieee(ic, i,
- + flags & ~IEEE80211_CHAN_HT);
- + if (cent == NULL)
- + {
- + printf("%s: skip channel %d, could not find center channel\n",
- + device_get_nameunit(sc->sc_dev), i);
- + continue;
- + }
- +
- + /* find the extension channel */
- +
- + ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
- + flags & ~IEEE80211_CHAN_HT);
- + if (ext == NULL)
- + {
- + printf("%s: skip channel %d, could not find extension channel\n",
- + device_get_nameunit(sc->sc_dev), i);
- + continue;
- + }
- +
- + c = &ic->ic_channels[ic->ic_nchans++];
- +
- + *c = *cent;
- + c->ic_extieee = ext->ic_ieee;
- + c->ic_flags &= ~IEEE80211_CHAN_HT;
- + c->ic_flags |= IEEE80211_CHAN_HT40U;
- +
- + c = &ic->ic_channels[ic->ic_nchans++];
- +
- + *c = *ext;
- + c->ic_extieee = cent->ic_ieee;
- + c->ic_flags &= ~IEEE80211_CHAN_HT;
- + c->ic_flags |= IEEE80211_CHAN_HT40D;
- + }
- +
- + for (i = 100; i <= 140; i += 4)
- + {
- + flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
- +
- + /* find the center channel */
- +
- + cent = ieee80211_find_channel_byieee(ic, i,
- + flags & ~IEEE80211_CHAN_HT);
- + if (cent == NULL)
- + {
- + printf("%s: skip channel %d, could not find center channel\n",
- + device_get_nameunit(sc->sc_dev), i);
- + continue;
- + }
- +
- + /* find the extension channel */
- +
- + ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
- + flags & ~IEEE80211_CHAN_HT);
- + if (ext == NULL)
- + {
- + printf("%s: skip channel %d, could not find extension channel\n",
- + device_get_nameunit(sc->sc_dev), i);
- + continue;
- + }
- +
- + c = &ic->ic_channels[ic->ic_nchans++];
- +
- + *c = *cent;
- + c->ic_extieee = ext->ic_ieee;
- + c->ic_flags &= ~IEEE80211_CHAN_HT;
- + c->ic_flags |= IEEE80211_CHAN_HT40U;
- +
- + c = &ic->ic_channels[ic->ic_nchans++];
- +
- + *c = *ext;
- + c->ic_extieee = cent->ic_ieee;
- + c->ic_flags &= ~IEEE80211_CHAN_HT;
- + c->ic_flags |= IEEE80211_CHAN_HT40D;
- + }
- +
- + for (i = 149; i <= 165; i += 4)
- + {
- + flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
- +
- + /* find the center channel */
- +
- + cent = ieee80211_find_channel_byieee(ic, i,
- + flags & ~IEEE80211_CHAN_HT);
- + if (cent == NULL)
- + {
- + printf("%s: skip channel %d, could not find center channel\n",
- + device_get_nameunit(sc->sc_dev), i);
- + continue;
- + }
- +
- + /* find the extension channel */
- +
- + ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
- + flags & ~IEEE80211_CHAN_HT);
- + if (ext == NULL)
- + {
- + printf("%s: skip channel %d, could not find extension channel\n",
- + device_get_nameunit(sc->sc_dev), i);
- + continue;
- + }
- +
- + c = &ic->ic_channels[ic->ic_nchans++];
- +
- + *c = *cent;
- + c->ic_extieee = ext->ic_ieee;
- + c->ic_flags &= ~IEEE80211_CHAN_HT;
- + c->ic_flags |= IEEE80211_CHAN_HT40U;
- +
- + c = &ic->ic_channels[ic->ic_nchans++];
- +
- + *c = *ext;
- + c->ic_extieee = cent->ic_ieee;
- + c->ic_flags &= ~IEEE80211_CHAN_HT;
- + c->ic_flags |= IEEE80211_CHAN_HT40D;
- + }
- + }
- + }
- +
- + /*
- + * rt2860_init_locked
- + */
- + static void rt2860_init_locked(void *priv)
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + int error, i, ntries;
- + uint32_t tmp, stacnt[6];
- +
- + sc = priv;
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_ANY,
- + "%s: initializing\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + RT2860_SOFTC_ASSERT_LOCKED(sc);
- +
- + if (sc->mac_rev != 0x28720200)
- + {
- + if (!(sc->flags & RT2860_SOFTC_FLAGS_UCODE_LOADED))
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_ANY,
- + "%s: loading 8051 microcode\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + error = rt2860_io_mcu_load_ucode(sc, rt2860_ucode, sizeof(rt2860_ucode));
- + if (error != 0)
- + {
- + printf("%s: could not load 8051 microcode\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_ANY,
- + "%s: 8051 microcode was successfully loaded\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->flags |= RT2860_SOFTC_FLAGS_UCODE_LOADED;
- + }
- + }
- + else
- + {
- + sc->flags |= RT2860_SOFTC_FLAGS_UCODE_LOADED;
- +
- + /* Blink every TX */
- + #define LED_CFG_LED_POLARITY (1<<30)
- + #define LED_CFG_Y_LED_MODE_ONTX (1<<28)
- + #define LED_CFG_G_LED_MODE_ONTX (1<<26)
- + #define LED_CFG_R_LED_MODE_ONTX (1<<24)
- + #define LED_CFG_SLOW_BLK_TIME (0x03<<16) /* sec */
- + #define LED_CFG_LED_OFF_TIME (0x1e<<8) /* msec */
- + #define LED_CFG_LED_ON_TIME (0x46) /* msec */
- + rt2860_io_mac_write(sc, RT2860_REG_LED_CFG,
- + LED_CFG_LED_POLARITY |
- + LED_CFG_Y_LED_MODE_ONTX |
- + LED_CFG_G_LED_MODE_ONTX |
- + LED_CFG_R_LED_MODE_ONTX |
- + LED_CFG_SLOW_BLK_TIME |
- + LED_CFG_LED_OFF_TIME |
- + LED_CFG_LED_ON_TIME);
- + }
- +
- + rt2860_io_mac_write(sc, RT2860_REG_PWR_PIN_CFG, 0x2);
- +
- + /* disable DMA engine */
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_WPDMA_GLO_CFG);
- +
- + tmp &= 0xff0;
- + tmp |= RT2860_REG_TX_WB_DDONE;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WPDMA_RST_IDX, 0xffffffff);
- +
- + /* PBF hardware reset */
- +
- + rt2860_io_mac_write(sc, RT2860_REG_PBF_SYS_CTRL, 0xe1f);
- + rt2860_io_mac_write(sc, RT2860_REG_PBF_SYS_CTRL, 0xe00);
- +
- + /* wait while DMA engine is busy */
- +
- + for (ntries = 0; ntries < 100; ntries++)
- + {
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_WPDMA_GLO_CFG);
- + if (!(tmp & (RT2860_REG_TX_DMA_BUSY | RT2860_REG_RX_DMA_BUSY)))
- + break;
- +
- + DELAY(1000);
- + }
- +
- + if (ntries == 100)
- + {
- + printf("%s: timeout waiting for DMA engine\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + tmp &= 0xff0;
- + tmp |= RT2860_REG_TX_WB_DDONE;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
- +
- + /* reset Rx and Tx rings */
- +
- + tmp = RT2860_REG_RST_IDX_RX |
- + RT2860_REG_RST_IDX_TX_MGMT |
- + RT2860_REG_RST_IDX_TX_HCCA |
- + RT2860_REG_RST_IDX_TX_AC3 |
- + RT2860_REG_RST_IDX_TX_AC2 |
- + RT2860_REG_RST_IDX_TX_AC1 |
- + RT2860_REG_RST_IDX_TX_AC0;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WPDMA_RST_IDX, tmp);
- +
- + /* PBF hardware reset */
- +
- + rt2860_io_mac_write(sc, RT2860_REG_PBF_SYS_CTRL, 0xe1f);
- + rt2860_io_mac_write(sc, RT2860_REG_PBF_SYS_CTRL, 0xe00);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_PWR_PIN_CFG, 0x3);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SYS_CTRL,
- + RT2860_REG_MAC_SRST | RT2860_REG_BBP_HRST);
- + rt2860_io_mac_write(sc, RT2860_REG_SYS_CTRL, 0);
- +
- + /* init Tx power per rate */
- +
- + for (i = 0; i < RT2860_SOFTC_TXPOW_RATE_COUNT; i++)
- + {
- + if (sc->txpow_rate_20mhz[i] == 0xffffffff)
- + continue;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_TX_PWR_CFG(i),
- + sc->txpow_rate_20mhz[i]);
- + }
- +
- + for (i = 0; i < RT2860_DEF_MAC_SIZE; i++)
- + rt2860_io_mac_write(sc, rt2860_def_mac[i].reg,
- + rt2860_def_mac[i].val);
- +
- + /* wait while MAC is busy */
- +
- + for (ntries = 0; ntries < 100; ntries++)
- + {
- + if (!(rt2860_io_mac_read(sc, RT2860_REG_STATUS_CFG) &
- + (RT2860_REG_STATUS_TX_BUSY | RT2860_REG_STATUS_RX_BUSY)))
- + break;
- +
- + DELAY(1000);
- + }
- +
- + if (ntries == 100)
- + {
- + printf("%s: timeout waiting for MAC\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + /* clear Host to MCU mailbox */
- +
- + rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX_BBP_AGENT, 0);
- + rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX, 0);
- +
- + rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_BOOT,
- + RT2860_REG_H2M_TOKEN_NO_INTR, 0);
- +
- + DELAY(1000);
- +
- + error = rt2860_init_bbp(sc);
- + if (error != 0)
- + goto fail;
- +
- + /* set up maximum buffer sizes */
- +
- + tmp = (1 << 12) | RT2860_MAX_AGG_SIZE;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_MAX_LEN_CFG, tmp);
- +
- + if (sc->mac_rev == 0x28720200)
- + {
- + /* set max. PSDU length from 16K to 32K bytes */
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_MAX_LEN_CFG);
- +
- + tmp &= ~(3 << 12);
- + tmp |= (2 << 12);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_MAX_LEN_CFG, tmp);
- + }
- +
- + if (sc->mac_rev >= 0x28720200 && sc->mac_rev < 0x30700200)
- + {
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_MAX_LEN_CFG);
- +
- + tmp &= 0xfff;
- + tmp |= 0x2000;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_MAX_LEN_CFG, tmp);
- + }
- +
- + /* set mac address */
- +
- + rt2860_asic_set_macaddr(sc, IF_LLADDR(ifp));
- +
- + /* clear statistic registers */
- +
- + rt2860_io_mac_read_multi(sc, RT2860_REG_RX_STA_CNT0,
- + stacnt, sizeof(stacnt));
- +
- + /* set RTS threshold */
- +
- + rt2860_asic_update_rtsthreshold(sc);
- +
- + /* set Tx power */
- +
- + rt2860_asic_update_txpower(sc);
- +
- + /* set up protection mode */
- +
- + sc->tx_ampdu_sessions = 0;
- +
- + rt2860_asic_updateprot(sc);
- +
- + /* clear beacon frame space (entries = 8, entry size = 512) */
- +
- + rt2860_io_mac_set_region_4(sc, RT2860_REG_BEACON_BASE(0), 0, 1024);
- +
- + taskqueue_unblock(sc->taskqueue);
- +
- + /* init Tx rings (4 EDCAs + HCCA + MGMT) */
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_COUNT; i++)
- + rt2860_reset_tx_ring(sc, &sc->tx_ring[i]);
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_COUNT; i++)
- + {
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_TX_BASE_PTR(i),
- + sc->tx_ring[i].desc_phys_addr);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_TX_MAX_CNT(i),
- + RT2860_SOFTC_TX_RING_DESC_COUNT);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_TX_CTX_IDX(i), 0);
- + }
- +
- + /* init Rx ring */
- +
- + rt2860_reset_rx_ring(sc, &sc->rx_ring);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_RX_BASE_PTR,
- + sc->rx_ring.desc_phys_addr);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_RX_MAX_CNT,
- + RT2860_SOFTC_RX_RING_DATA_COUNT);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_RX_CALC_IDX,
- + RT2860_SOFTC_RX_RING_DATA_COUNT - 1);
- +
- + /* wait while DMA engine is busy */
- +
- + for (ntries = 0; ntries < 100; ntries++)
- + {
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_WPDMA_GLO_CFG);
- + if (!(tmp & (RT2860_REG_TX_DMA_BUSY | RT2860_REG_RX_DMA_BUSY)))
- + break;
- +
- + DELAY(1000);
- + }
- +
- + if (ntries == 100)
- + {
- + printf("%s: timeout waiting for DMA engine\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + tmp &= 0xff0;
- + tmp |= RT2860_REG_TX_WB_DDONE;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
- +
- + /* disable interrupts mitigation */
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_DELAY_INT_CFG, 0);
- +
- + /* select Main antenna for 1T1R devices */
- + if (sc->rf_rev == RT2860_EEPROM_RF_2020 ||
- + sc->rf_rev == RT2860_EEPROM_RF_3020 ||
- + sc->rf_rev == RT2860_EEPROM_RF_3320)
- + rt3090_set_rx_antenna(sc, 0);
- +
- + /* send LEDs operating mode to microcontroller */
- + rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_LED1,
- + RT2860_REG_H2M_TOKEN_NO_INTR, sc->led_off[0]);
- + rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_LED2,
- + RT2860_REG_H2M_TOKEN_NO_INTR, sc->led_off[1]);
- + rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_LED3,
- + RT2860_REG_H2M_TOKEN_NO_INTR, sc->led_off[2]);
- +
- + /* turn radio LED on */
- +
- + rt2860_led_cmd(sc, RT2860_LED_CMD_RADIO_ON);
- +
- + /* write vendor-specific BBP values (from EEPROM) */
- +
- + for (i = 0; i < RT2860_SOFTC_BBP_EEPROM_COUNT; i++)
- + {
- + if (sc->bbp_eeprom[i].reg == 0x00 ||
- + sc->bbp_eeprom[i].reg == 0xff)
- + continue;
- +
- + rt2860_io_bbp_write(sc, sc->bbp_eeprom[i].reg,
- + sc->bbp_eeprom[i].val);
- + }
- +
- + if ((sc->mac_rev & 0xffff0000) >= 0x30710000)
- + rt3090_rf_init(sc);
- +
- + if (sc->mac_rev != 0x28720200) {
- + /* 0x28720200 don`t have RT2860_REG_SCHDMA_GPIO_CTRL_CFG */
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_GPIO_CTRL_CFG);
- + if (tmp & (1 << 2)) {
- + rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_SLEEP,
- + RT2860_REG_H2M_TOKEN_RADIOOFF, 0x02ff);
- + rt2860_io_mcu_cmd_check(sc, RT2860_REG_H2M_TOKEN_RADIOOFF);
- +
- + rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_WAKEUP,
- + RT2860_REG_H2M_TOKEN_WAKEUP, 0);
- + rt2860_io_mcu_cmd_check(sc, RT2860_REG_H2M_TOKEN_WAKEUP);
- + }
- + }
- +
- + if ((sc->mac_rev & 0xffff0000) >= 0x30710000)
- + rt3090_rf_wakeup(sc);
- +
- + /* disable non-existing Rx chains */
- +
- + tmp = rt2860_io_bbp_read(sc, 3);
- +
- + tmp &= ~((1 << 4) | (1 << 3));
- +
- + if (sc->nrxpath == 3)
- + tmp |= (1 << 4);
- + else if (sc->nrxpath == 2)
- + tmp |= (1 << 3);
- +
- + rt2860_io_bbp_write(sc, 3, tmp);
- +
- + /* disable non-existing Tx chains */
- +
- + tmp = rt2860_io_bbp_read(sc, 1);
- +
- + tmp &= ~((1 << 4) | (1 << 3));
- +
- + if (sc->ntxpath == 2)
- + tmp |= (1 << 4);
- +
- + rt2860_io_bbp_write(sc, 1, tmp);
- +
- + if ((sc->mac_rev & 0xffff0000) >= 0x30710000)
- + rt3090_rf_setup(sc);
- +
- + if (sc->rf_rev == RT2860_EEPROM_RF_3022)
- + {
- + /* calibrate RF */
- + tmp = rt2860_io_rf_read(sc, 30);
- + tmp |= 0x80;
- + rt2860_io_rf_write(sc, 30, tmp);
- + DELAY(1000);
- + tmp &= 0x7F;
- + rt2860_io_rf_write(sc, 30, tmp);
- +
- + /* Initialize RF register to default value */
- + rt2860_io_rf_load_defaults(sc);
- + }
- +
- + /* set current channel */
- + rt2860_rf_set_chan(sc, ic->ic_curchan);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WMM_TXOP0_CFG, 0);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WMM_TXOP1_CFG,
- + (48 << 16) | 96);
- +
- + if ((sc->mac_rev & 0xffff) != 0x0101)
- + rt2860_io_mac_write(sc, RT2860_REG_TX_TXOP_CTRL_CFG, 0x583f);
- +
- + /* clear pending interrupts */
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_INT_STATUS, 0xffffffff);
- +
- + /* enable interrupts */
- +
- + tmp = RT2860_REG_INT_TX_COHERENT |
- + RT2860_REG_INT_RX_COHERENT |
- + RT2860_REG_INT_GP_TIMER |
- + RT2860_REG_INT_AUTO_WAKEUP |
- + RT2860_REG_INT_FIFO_STA_FULL |
- + RT2860_REG_INT_PRE_TBTT |
- + RT2860_REG_INT_TBTT |
- + RT2860_REG_INT_TXRX_COHERENT |
- + RT2860_REG_INT_MCU_CMD |
- + RT2860_REG_INT_TX_MGMT_DONE |
- + RT2860_REG_INT_TX_HCCA_DONE |
- + RT2860_REG_INT_TX_AC3_DONE |
- + RT2860_REG_INT_TX_AC2_DONE |
- + RT2860_REG_INT_TX_AC1_DONE |
- + RT2860_REG_INT_TX_AC0_DONE |
- + RT2860_REG_INT_RX_DONE;
- +
- + sc->intr_enable_mask = tmp;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_INT_MASK, tmp);
- +
- + if (rt2860_txrx_enable(sc) != 0)
- + goto fail;
- +
- + /* clear garbage interrupts */
- +
- + tmp = rt2860_io_mac_read(sc, 0x1300);
- +
- + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- + ifp->if_drv_flags |= IFF_DRV_RUNNING;
- +
- + sc->periodic_round = 0;
- +
- + callout_reset(&sc->periodic_ch, hz / 10, rt2860_periodic, sc);
- +
- + return;
- +
- + fail:
- +
- + rt2860_stop_locked(sc);
- + }
- +
- + /*
- + * rt2860_init
- + */
- + static void rt2860_init(void *priv)
- + {
- + struct rt2860_softc *sc;
- +
- + sc = priv;
- +
- + RT2860_SOFTC_LOCK(sc);
- +
- + rt2860_init_locked(sc);
- +
- + RT2860_SOFTC_UNLOCK(sc);
- + }
- +
- + /*
- + * rt2860_init_bbp
- + */
- + static int rt2860_init_bbp(struct rt2860_softc *sc)
- + {
- + int ntries, i;
- + uint8_t tmp;
- +
- + for (ntries = 0; ntries < 20; ntries++)
- + {
- + tmp = rt2860_io_bbp_read(sc, 0);
- + if (tmp != 0x00 && tmp != 0xff)
- + break;
- + }
- +
- + if (tmp == 0x00 || tmp == 0xff)
- + {
- + printf("%s: timeout waiting for BBP to wakeup\n",
- + device_get_nameunit(sc->sc_dev));
- + return ETIMEDOUT;
- + }
- +
- + for (i = 0; i < RT2860_DEF_BBP_SIZE; i++)
- + rt2860_io_bbp_write(sc, rt2860_def_bbp[i].reg,
- + rt2860_def_bbp[i].val);
- +
- + if ((sc->mac_rev & 0xffff) != 0x0101)
- + rt2860_io_bbp_write(sc, 84, 0x19);
- +
- + if (sc->mac_rev == 0x28600100)
- + {
- + rt2860_io_bbp_write(sc, 69, 0x16);
- + rt2860_io_bbp_write(sc, 73, 0x12);
- + }
- +
- + return 0;
- + }
- +
- + /*
- + * rt2860_stop_locked
- + */
- + static void rt2860_stop_locked(void *priv)
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + uint32_t tmp;
- +
- + sc = priv;
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_ANY,
- + "%s: stopping\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + RT2860_SOFTC_ASSERT_LOCKED(sc);
- +
- + sc->sc_tx_timer = 0;
- +
- + if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- + rt2860_led_cmd(sc, RT2860_LED_CMD_RADIO_OFF);
- +
- + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
- +
- + callout_stop(&sc->periodic_ch);
- + callout_stop(&sc->tx_watchdog_ch);
- +
- + RT2860_SOFTC_UNLOCK(sc);
- +
- + taskqueue_block(sc->taskqueue);
- +
- + taskqueue_drain(sc->taskqueue, &sc->rx_done_task);
- + taskqueue_drain(sc->taskqueue, &sc->tx_done_task);
- + taskqueue_drain(sc->taskqueue, &sc->fifo_sta_full_task);
- + taskqueue_drain(sc->taskqueue, &sc->periodic_task);
- +
- + RT2860_SOFTC_LOCK(sc);
- +
- + /* clear key tables */
- +
- + rt2860_asic_clear_keytables(sc);
- +
- + /* disable interrupts */
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_INT_MASK, 0);
- +
- + /* disable Tx/Rx */
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_SYS_CTRL);
- +
- + tmp &= ~(RT2860_REG_RX_ENABLE | RT2860_REG_TX_ENABLE);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SYS_CTRL, tmp);
- +
- + /* reset adapter */
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SYS_CTRL,
- + RT2860_REG_MAC_SRST | RT2860_REG_BBP_HRST);
- + rt2860_io_mac_write(sc, RT2860_REG_SYS_CTRL, 0);
- + }
- +
- + /*
- + * rt2860_stop
- + */
- + static void rt2860_stop(void *priv)
- + {
- + struct rt2860_softc *sc;
- +
- + sc = priv;
- +
- + RT2860_SOFTC_LOCK(sc);
- +
- + rt2860_stop_locked(sc);
- +
- + RT2860_SOFTC_UNLOCK(sc);
- + }
- +
- + /*
- + * rt2860_start
- + */
- + static void rt2860_start(struct ifnet *ifp)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211_node *ni;
- + struct mbuf *m;
- + int qid;
- +
- + sc = ifp->if_softc;
- +
- + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- + return;
- +
- + for (;;)
- + {
- + IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- + if (m == NULL)
- + break;
- +
- + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
- +
- + m->m_pkthdr.rcvif = NULL;
- +
- + qid = M_WME_GETAC(m);
- +
- + RT2860_SOFTC_TX_RING_LOCK(&sc->tx_ring[qid]);
- +
- + if (sc->tx_ring[qid].data_queued >= RT2860_SOFTC_TX_RING_DATA_COUNT)
- + {
- + RT2860_SOFTC_TX_RING_UNLOCK(&sc->tx_ring[qid]);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_TX,
- + "%s: if_start: Tx ring with qid=%d is full\n",
- + device_get_nameunit(sc->sc_dev), qid);
- +
- + m_freem(m);
- + ieee80211_free_node(ni);
- +
- + ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- + ifp->if_oerrors++;
- +
- + sc->tx_data_queue_full[qid]++;
- +
- + break;
- + }
- +
- + if (rt2860_tx_data(sc, m, ni, qid) != 0)
- + {
- + RT2860_SOFTC_TX_RING_UNLOCK(&sc->tx_ring[qid]);
- +
- + ieee80211_free_node(ni);
- +
- + ifp->if_oerrors++;
- +
- + break;
- + }
- +
- + RT2860_SOFTC_TX_RING_UNLOCK(&sc->tx_ring[qid]);
- +
- + rt2860_drain_fifo_stats(sc);
- +
- + sc->sc_tx_timer = RT2860_TX_WATCHDOG_TIMEOUT;
- +
- + callout_reset(&sc->tx_watchdog_ch, hz, rt2860_tx_watchdog, sc);
- + }
- + }
- +
- + /*
- + * rt2860_ioctl
- + */
- + static int rt2860_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifreq *ifr;
- + int error, startall;
- +
- + sc = ifp->if_softc;
- + ic = ifp->if_l2com;
- + ifr = (struct ifreq *) data;
- +
- + error = 0;
- +
- + switch (cmd)
- + {
- + case SIOCSIFFLAGS:
- + startall = 0;
- +
- + RT2860_SOFTC_LOCK(sc);
- +
- + if (ifp->if_flags & IFF_UP)
- + {
- + if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- + {
- + if ((ifp->if_flags ^ sc->if_flags) & IFF_PROMISC)
- + rt2860_asic_update_promisc(sc);
- + }
- + else
- + {
- + rt2860_init_locked(sc);
- + startall = 1;
- + }
- + }
- + else
- + {
- + if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- + rt2860_stop_locked(sc);
- + }
- +
- + sc->if_flags = ifp->if_flags;
- +
- + RT2860_SOFTC_UNLOCK(sc);
- +
- + if (startall)
- + ieee80211_start_all(ic);
- + break;
- +
- + case SIOCGIFMEDIA:
- + case SIOCSIFMEDIA:
- + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- + break;
- +
- + case SIOCGIFADDR:
- + error = ether_ioctl(ifp, cmd, data);
- + break;
- +
- + default:
- + error = EINVAL;
- + break;
- + }
- +
- + return error;
- + }
- +
- + /*
- + * rt2860_vap_create
- + */
- + static struct ieee80211vap *rt2860_vap_create(struct ieee80211com *ic,
- + const char name[IFNAMSIZ], int unit, int opmode, int flags,
- + const uint8_t bssid[IEEE80211_ADDR_LEN],
- + const uint8_t mac[IEEE80211_ADDR_LEN])
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- + struct rt2860_softc_vap *rvap;
- + struct ieee80211vap *vap;
- +
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_STATE,
- + "%s: VAP create: opmode=%s\n",
- + device_get_nameunit(sc->sc_dev),
- + ieee80211_opmode_name[opmode]);
- +
- + switch (opmode)
- + {
- + case IEEE80211_M_IBSS:
- + case IEEE80211_M_STA:
- + case IEEE80211_M_AHDEMO:
- + case IEEE80211_M_HOSTAP:
- + case IEEE80211_M_MBSS:
- + if ((sc->napvaps + sc->nadhocvaps + sc->nstavaps) != 0)
- + {
- + if_printf(ifp, "only 1 VAP supported\n");
- + return NULL;
- + }
- +
- + if (opmode == IEEE80211_M_STA)
- + flags |= IEEE80211_CLONE_NOBEACONS;
- + break;
- +
- + case IEEE80211_M_WDS:
- + if (sc->napvaps == 0)
- + {
- + if_printf(ifp, "WDS only supported in AP mode\n");
- + return NULL;
- + }
- + break;
- +
- + case IEEE80211_M_MONITOR:
- + break;
- +
- + default:
- + if_printf(ifp, "unknown opmode %d\n", opmode);
- + return NULL;
- + }
- +
- + rvap = (struct rt2860_softc_vap *) malloc(sizeof(struct rt2860_softc_vap),
- + M_80211_VAP, M_NOWAIT | M_ZERO);
- + if (rvap == NULL)
- + return NULL;
- +
- + vap = &rvap->vap;
- +
- + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
- +
- + rvap->newstate = vap->iv_newstate;
- + vap->iv_newstate = rt2860_vap_newstate;
- +
- + vap->iv_reset = rt2860_vap_reset;
- + vap->iv_key_update_begin = rt2860_vap_key_update_begin;
- + vap->iv_key_update_end = rt2860_vap_key_update_end;
- + vap->iv_key_set = rt2860_vap_key_set;
- + vap->iv_key_delete = rt2860_vap_key_delete;
- + vap->iv_update_beacon = rt2860_vap_update_beacon;
- +
- + rt2860_amrr_init(&rvap->amrr, vap,
- + sc->ntxpath,
- + RT2860_AMRR_MIN_SUCCESS_THRESHOLD,
- + RT2860_AMRR_MAX_SUCCESS_THRESHOLD,
- + 500);
- +
- + vap->iv_max_aid = RT2860_SOFTC_STAID_COUNT;
- +
- + /* overwrite default Rx A-MPDU factor */
- +
- + vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_32K;
- + vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_NA;
- + vap->iv_ampdu_limit = vap->iv_ampdu_rxmax;
- +
- + ieee80211_vap_attach(vap, rt2860_media_change, ieee80211_media_status);
- +
- + switch (vap->iv_opmode)
- + {
- + case IEEE80211_M_HOSTAP:
- + case IEEE80211_M_MBSS:
- + case IEEE80211_M_AHDEMO:
- + sc->napvaps++;
- + break;
- +
- + case IEEE80211_M_IBSS:
- + sc->nadhocvaps++;
- + break;
- +
- + case IEEE80211_M_STA:
- + sc->nstavaps++;
- + break;
- +
- + case IEEE80211_M_WDS:
- + sc->nwdsvaps++;
- + break;
- +
- + default:
- + break;
- + }
- +
- + sc->nvaps++;
- +
- + if (sc->napvaps > 0)
- + ic->ic_opmode = IEEE80211_M_HOSTAP;
- + else if (sc->nadhocvaps > 0)
- + ic->ic_opmode = IEEE80211_M_IBSS;
- + else if (sc->nstavaps > 0)
- + ic->ic_opmode = IEEE80211_M_STA;
- + else
- + ic->ic_opmode = opmode;
- +
- + return vap;
- + }
- +
- + /*
- + * rt2860_vap_delete
- + */
- + static void rt2860_vap_delete(struct ieee80211vap *vap)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct rt2860_softc_vap *rvap;
- + enum ieee80211_opmode opmode;
- +
- + ic = vap->iv_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- + rvap = (struct rt2860_softc_vap *) vap;
- + opmode = vap->iv_opmode;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_STATE,
- + "%s: VAP delete: opmode=%s\n",
- + device_get_nameunit(sc->sc_dev), ieee80211_opmode_name[opmode]);
- +
- + rt2860_amrr_cleanup(&rvap->amrr);
- +
- + ieee80211_vap_detach(vap);
- +
- + if (rvap->beacon_mbuf != NULL)
- + {
- + m_free(rvap->beacon_mbuf);
- + rvap->beacon_mbuf = NULL;
- + }
- +
- + switch (opmode)
- + {
- + case IEEE80211_M_HOSTAP:
- + case IEEE80211_M_MBSS:
- + case IEEE80211_M_AHDEMO:
- + sc->napvaps--;
- + break;
- +
- + case IEEE80211_M_IBSS:
- + sc->nadhocvaps--;
- + break;
- +
- + case IEEE80211_M_STA:
- + sc->nstavaps--;
- + break;
- +
- + case IEEE80211_M_WDS:
- + sc->nwdsvaps--;
- + break;
- +
- + default:
- + break;
- + }
- +
- + sc->nvaps--;
- +
- + if (sc->napvaps > 0)
- + ic->ic_opmode = IEEE80211_M_HOSTAP;
- + else if (sc->nadhocvaps > 0)
- + ic->ic_opmode = IEEE80211_M_IBSS;
- + else if (sc->nstavaps > 0)
- + ic->ic_opmode = IEEE80211_M_STA;
- +
- + free(rvap, M_80211_VAP);
- + }
- +
- + /*
- + * rt2860_reset_vap
- + */
- + static int rt2860_vap_reset(struct ieee80211vap *vap, u_long cmd)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct rt2860_softc_vap *rvap;
- + int error;
- +
- + ic = vap->iv_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- + rvap = (struct rt2860_softc_vap *) vap;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_STATE,
- + "%s: VAP reset: cmd=%lu\n",
- + device_get_nameunit(sc->sc_dev), cmd);
- +
- + error = 0;
- +
- + switch (cmd)
- + {
- + case IEEE80211_IOC_RTSTHRESHOLD:
- + case IEEE80211_IOC_AMSDU:
- + rt2860_asic_update_rtsthreshold(sc);
- + break;
- +
- + case IEEE80211_IOC_PROTMODE:
- + case IEEE80211_IOC_HTPROTMODE:
- + rt2860_asic_updateprot(sc);
- + break;
- +
- + case IEEE80211_IOC_TXPOWER:
- + rt2860_asic_update_txpower(sc);
- + break;
- +
- + case IEEE80211_IOC_BURST:
- + rt2860_asic_updateslot(sc);
- + break;
- +
- + case IEEE80211_IOC_SHORTGI:
- + case IEEE80211_IOC_AMPDU_DENSITY:
- + case IEEE80211_IOC_SMPS:
- + break;
- +
- + default:
- + error = ENETRESET;
- + break;
- + }
- +
- + return error;
- + }
- +
- + /*
- + * rt2860_vap_newstate
- + */
- + static int rt2860_vap_newstate(struct ieee80211vap *vap,
- + enum ieee80211_state nstate, int arg)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct rt2860_softc_vap *rvap;
- + struct ieee80211_node *ni;
- + enum ieee80211_state ostate;
- + int error;
- +
- + ic = vap->iv_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- + rvap = (struct rt2860_softc_vap *) vap;
- +
- + ostate = vap->iv_state;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_STATE,
- + "%s: VAP newstate: %s -> %s\n",
- + device_get_nameunit(sc->sc_dev),
- + ieee80211_state_name[ostate], ieee80211_state_name[nstate]);
- +
- + error = rvap->newstate(vap, nstate, arg);
- + if (error != 0)
- + return error;
- +
- + IEEE80211_UNLOCK(ic);
- +
- + RT2860_SOFTC_LOCK(sc);
- +
- + /* turn link LED off */
- +
- + if (nstate != IEEE80211_S_RUN)
- + rt2860_led_cmd(sc, RT2860_LED_CMD_RADIO_OFF);
- +
- + switch (nstate)
- + {
- + case IEEE80211_S_INIT:
- + rt2860_asic_disable_tsf_sync(sc);
- + break;
- +
- + case IEEE80211_S_RUN:
- + ni = vap->iv_bss;
- +
- + rt2860_rf_set_chan(sc, ni->ni_chan);
- +
- + if (vap->iv_opmode != IEEE80211_M_MONITOR)
- + {
- + rt2860_asic_enable_mrr(sc);
- + rt2860_asic_set_txpreamble(sc);
- + rt2860_asic_set_basicrates(sc);
- + rt2860_asic_update_txpower(sc);
- + rt2860_asic_set_bssid(sc, ni->ni_bssid);
- + }
- +
- + if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
- + vap->iv_opmode == IEEE80211_M_IBSS ||
- + vap->iv_opmode == IEEE80211_M_MBSS)
- + {
- + error = rt2860_beacon_alloc(sc, vap);
- + if (error != 0)
- + break;
- +
- + rt2860_asic_update_beacon(sc, vap);
- + }
- +
- + if (vap->iv_opmode != IEEE80211_M_MONITOR)
- + rt2860_asic_enable_tsf_sync(sc);
- +
- + /* turn link LED on */
- +
- + if (vap->iv_opmode != IEEE80211_M_MONITOR)
- + {
- + rt2860_led_cmd(sc, RT2860_LED_CMD_RADIO_ON |
- + (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) ?
- + RT2860_LED_CMD_LINK_2GHZ : RT2860_LED_CMD_LINK_5GHZ));
- + }
- + break;
- +
- + case IEEE80211_S_SLEEP:
- + break;
- +
- + default:
- + break;
- + }
- +
- + RT2860_SOFTC_UNLOCK(sc);
- +
- + IEEE80211_LOCK(ic);
- +
- + return error;
- + }
- +
- + /*
- + * rt2860_vap_key_update_begin
- + */
- + static void rt2860_vap_key_update_begin(struct ieee80211vap *vap)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- +
- + ic = vap->iv_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_KEY,
- + "%s: VAP key update begin\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + taskqueue_block(sc->taskqueue);
- +
- + IF_LOCK(&ifp->if_snd);
- + }
- +
- + /*
- + * rt2860_vap_key_update_end
- + */
- + static void rt2860_vap_key_update_end(struct ieee80211vap *vap)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- +
- + ic = vap->iv_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_KEY,
- + "%s: VAP key update end\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + IF_UNLOCK(&ifp->if_snd);
- +
- + taskqueue_unblock(sc->taskqueue);
- + }
- +
- + /*
- + * rt2860_vap_key_set
- + */
- + static int rt2860_vap_key_set(struct ieee80211vap *vap,
- + const struct ieee80211_key *k, const uint8_t mac[IEEE80211_ADDR_LEN])
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct ieee80211_node *ni;
- + struct rt2860_softc_node *rni;
- + uint16_t key_base, keymode_base;
- + uint8_t mode, vapid, wcid, iv[8];
- + uint32_t tmp;
- +
- + if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP &&
- + k->wk_cipher->ic_cipher != IEEE80211_CIPHER_TKIP &&
- + k->wk_cipher->ic_cipher != IEEE80211_CIPHER_AES_CCM)
- + return 0;
- +
- + ic = vap->iv_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- +
- + switch (k->wk_cipher->ic_cipher)
- + {
- + case IEEE80211_CIPHER_WEP:
- + if(k->wk_keylen < 8)
- + mode = RT2860_REG_CIPHER_MODE_WEP40;
- + else
- + mode = RT2860_REG_CIPHER_MODE_WEP104;
- + break;
- +
- + case IEEE80211_CIPHER_TKIP:
- + mode = RT2860_REG_CIPHER_MODE_TKIP;
- + break;
- +
- + case IEEE80211_CIPHER_AES_CCM:
- + mode = RT2860_REG_CIPHER_MODE_AES_CCMP;
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_KEY,
- + "%s: VAP key set: keyix=%d, keylen=%d, macaddr=%s, mode=%d, group=%d\n",
- + device_get_nameunit(sc->sc_dev), k->wk_keyix, k->wk_keylen, ether_sprintf(k->wk_macaddr),
- + mode, (k->wk_flags & IEEE80211_KEY_GROUP) ? 1 : 0);
- +
- + if (!(k->wk_flags & IEEE80211_KEY_GROUP))
- + {
- + /* install pairwise key */
- +
- + ni = ieee80211_find_vap_node(&ic->ic_sta, vap, mac);
- + if (!ni) {
- + printf("ieee80211_find_vap_node return 0\n");
- + return 0;
- + }
- + rni = (struct rt2860_softc_node *) ni;
- +
- + vapid = 0;
- + wcid = rni->staid;
- + key_base = RT2860_REG_PKEY(wcid);
- +
- + ieee80211_free_node(ni);
- +
- + if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP)
- + {
- + memset(iv, 0, 8);
- +
- + iv[3] = (k->wk_keyix << 6);
- + }
- + else
- + {
- + if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
- + {
- + iv[0] = (k->wk_keytsc >> 8);
- + iv[1] = ((iv[0] | 0x20) & 0x7f);
- + iv[2] = k->wk_keytsc;
- + }
- + else
- + {
- + /* AES CCMP */
- +
- + iv[0] = k->wk_keytsc;
- + iv[1] = k->wk_keytsc >> 8;
- + iv[2] = 0;
- + }
- +
- + iv[3] = ((k->wk_keyix << 6) | IEEE80211_WEP_EXTIV);
- + iv[4] = (k->wk_keytsc >> 16);
- + iv[5] = (k->wk_keytsc >> 24);
- + iv[6] = (k->wk_keytsc >> 32);
- + iv[7] = (k->wk_keytsc >> 40);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_KEY,
- + "%s: VAP key set: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n",
- + device_get_nameunit(sc->sc_dev),
- + iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]);
- + }
- +
- + rt2860_io_mac_write_multi(sc, RT2860_REG_IVEIV(wcid), iv, 8);
- +
- + if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
- + {
- + rt2860_io_mac_write_multi(sc, key_base, k->wk_key, 16);
- +
- + if (vap->iv_opmode != IEEE80211_M_HOSTAP)
- + {
- + rt2860_io_mac_write_multi(sc, key_base + 16, &k->wk_key[16], 8);
- + rt2860_io_mac_write_multi(sc, key_base + 24, &k->wk_key[24], 8);
- + }
- + else
- + {
- + rt2860_io_mac_write_multi(sc, key_base + 16, &k->wk_key[24], 8);
- + rt2860_io_mac_write_multi(sc, key_base + 24, &k->wk_key[16], 8);
- + }
- + }
- + else
- + {
- + rt2860_io_mac_write_multi(sc, key_base, k->wk_key, k->wk_keylen);
- + }
- +
- + tmp = ((vapid & RT2860_REG_VAP_MASK) << RT2860_REG_VAP_SHIFT) |
- + (mode << RT2860_REG_CIPHER_MODE_SHIFT) | RT2860_REG_PKEY_ENABLE;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_WCID_ATTR(wcid), tmp);
- + }
- +
- + if ((k->wk_flags & IEEE80211_KEY_GROUP) ||
- + (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP))
- + {
- + /* install group key */
- +
- + vapid = 0;
- + wcid = RT2860_WCID_MCAST;
- + key_base = RT2860_REG_SKEY(vapid, k->wk_keyix);
- + keymode_base = RT2860_REG_SKEY_MODE(vapid);
- +
- + if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
- + {
- + rt2860_io_mac_write_multi(sc, key_base, k->wk_key, 16);
- +
- + if (vap->iv_opmode != IEEE80211_M_HOSTAP)
- + {
- + rt2860_io_mac_write_multi(sc, key_base + 16, &k->wk_key[16], 8);
- + rt2860_io_mac_write_multi(sc, key_base + 24, &k->wk_key[24], 8);
- + }
- + else
- + {
- + rt2860_io_mac_write_multi(sc, key_base + 16, &k->wk_key[24], 8);
- + rt2860_io_mac_write_multi(sc, key_base + 24, &k->wk_key[16], 8);
- + }
- + }
- + else
- + {
- + rt2860_io_mac_write_multi(sc, key_base, k->wk_key, k->wk_keylen);
- + }
- +
- + tmp = rt2860_io_mac_read(sc, keymode_base);
- +
- + tmp &= ~(0xf << (k->wk_keyix * 4 + 16 * (vapid % 2)));
- + tmp |= (mode << (k->wk_keyix * 4 + 16 * (vapid % 2)));
- +
- + rt2860_io_mac_write(sc, keymode_base, tmp);
- +
- + if (vap->iv_opmode == IEEE80211_M_HOSTAP)
- + {
- + if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP)
- + {
- + memset(iv, 0, 8);
- +
- + iv[3] = (k->wk_keyix << 6);
- + }
- + else
- + {
- + if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
- + {
- + iv[0] = (k->wk_keytsc >> 8);
- + iv[1] = ((iv[0] | 0x20) & 0x7f);
- + iv[2] = k->wk_keytsc;
- + }
- + else
- + {
- + /* AES CCMP */
- +
- + iv[0] = k->wk_keytsc;
- + iv[1] = k->wk_keytsc >> 8;
- + iv[2] = 0;
- + }
- +
- + iv[3] = ((k->wk_keyix << 6) | IEEE80211_WEP_EXTIV);
- + iv[4] = (k->wk_keytsc >> 16);
- + iv[5] = (k->wk_keytsc >> 24);
- + iv[6] = (k->wk_keytsc >> 32);
- + iv[7] = (k->wk_keytsc >> 40);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_KEY,
- + "%s: VAP key set: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n",
- + device_get_nameunit(sc->sc_dev),
- + iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]);
- + }
- +
- + rt2860_io_mac_write_multi(sc, RT2860_REG_IVEIV(wcid), iv, 8);
- +
- + tmp = ((vapid & RT2860_REG_VAP_MASK) << RT2860_REG_VAP_SHIFT) |
- + (mode << RT2860_REG_CIPHER_MODE_SHIFT);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_WCID_ATTR(wcid), tmp);
- + }
- + }
- +
- + return 1;
- + }
- +
- + /*
- + * rt2860_vap_key_delete
- + */
- + static int rt2860_vap_key_delete(struct ieee80211vap *vap,
- + const struct ieee80211_key *k)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + uint8_t vapid, wcid;
- + uint32_t tmp;
- +
- + ic = vap->iv_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_KEY,
- + "%s: VAP key delete: keyix=%d, keylen=%d, macaddr=%s, group=%d\n",
- + device_get_nameunit(sc->sc_dev), k->wk_keyix, k->wk_keylen, ether_sprintf(k->wk_macaddr),
- + (k->wk_flags & IEEE80211_KEY_GROUP) ? 1 : 0);
- +
- + if (k->wk_flags & IEEE80211_KEY_GROUP)
- + {
- + /* remove group key */
- +
- + vapid = 0;
- + wcid = RT2860_WCID_MCAST;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_SKEY_MODE(vapid));
- +
- + tmp &= ~(0xf << (k->wk_keyix * 4 + 16 * (vapid % 2)));
- + tmp |= (RT2860_REG_CIPHER_MODE_NONE << (k->wk_keyix * 4 + 16 * (vapid % 2)));
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SKEY_MODE(vapid), tmp);
- +
- + if (vap->iv_opmode == IEEE80211_M_HOSTAP)
- + {
- + tmp = ((vapid & RT2860_REG_VAP_MASK) << RT2860_REG_VAP_SHIFT) |
- + (RT2860_REG_CIPHER_MODE_NONE << RT2860_REG_CIPHER_MODE_SHIFT) | RT2860_REG_PKEY_ENABLE;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_WCID_ATTR(wcid), tmp);
- + }
- + }
- +
- + return 1;
- + }
- +
- + /*
- + * rt2860_vap_update_beacon
- + */
- + static void rt2860_vap_update_beacon(struct ieee80211vap *vap, int what)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct rt2860_softc_vap *rvap;
- + struct mbuf *m;
- + struct ieee80211_beacon_offsets *bo;
- + int error;
- +
- + ic = vap->iv_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- + rvap = (struct rt2860_softc_vap *) vap;
- + m = rvap->beacon_mbuf;
- + bo = &rvap->beacon_offsets;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_BEACON,
- + "%s: VAP update beacon: what=%d\n",
- + device_get_nameunit(sc->sc_dev), what);
- +
- + setbit(bo->bo_flags, what);
- +
- + if (m == NULL)
- + {
- + error = rt2860_beacon_alloc(sc, vap);
- + if (error != 0)
- + return;
- +
- + m = rvap->beacon_mbuf;
- + }
- +
- + ieee80211_beacon_update(vap->iv_bss, bo, m, 0);
- +
- + rt2860_asic_update_beacon(sc, vap);
- + }
- +
- + /*
- + * rt2860_media_change
- + */
- + static int rt2860_media_change(struct ifnet *ifp)
- + {
- + int error;
- +
- + error = ieee80211_media_change(ifp);
- +
- + return (error == ENETRESET ? 0 : error);
- + }
- +
- + /*
- + * rt2860_node_alloc
- + */
- + static struct ieee80211_node *rt2860_node_alloc(struct ieee80211vap *vap,
- + const uint8_t mac[IEEE80211_ADDR_LEN])
- + {
- + return malloc(sizeof(struct rt2860_softc_node),
- + M_80211_NODE, M_NOWAIT | M_ZERO);
- + }
- +
- + /*
- + * rt2860_node_cleanup
- + */
- + static void rt2860_node_cleanup(struct ieee80211_node *ni)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct rt2860_softc_node *rni;
- + uint8_t vapid, wcid;
- + uint32_t tmp;
- +
- + ic = ni->ni_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- + rni = (struct rt2860_softc_node *) ni;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_NODE,
- + "%s: node cleanup: macaddr=%s, associd=0x%04x, staid=0x%02x\n",
- + device_get_nameunit(sc->sc_dev), ether_sprintf(ni->ni_macaddr),
- + ni->ni_associd, rni->staid);
- +
- + if (rni->staid != 0)
- + {
- + vapid = 0;
- + wcid = rni->staid;
- +
- + tmp = ((vapid & RT2860_REG_VAP_MASK) << RT2860_REG_VAP_SHIFT) |
- + (RT2860_REG_CIPHER_MODE_NONE << RT2860_REG_CIPHER_MODE_SHIFT) | RT2860_REG_PKEY_ENABLE;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_WCID_ATTR(wcid), tmp);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_WCID(wcid), 0x00000000);
- + rt2860_io_mac_write(sc, RT2860_REG_WCID(wcid) + 4, 0x00000000);
- +
- + rt2860_staid_delete(sc, rni->staid);
- +
- + rni->staid = 0;
- + }
- +
- + sc->node_cleanup(ni);
- + }
- +
- + /*
- + * rt2860_node_getmimoinfo
- + */
- + static void rt2860_node_getmimoinfo(const struct ieee80211_node *ni,
- + struct ieee80211_mimo_info *mi)
- + {
- + const struct rt2860_softc_node *rni;
- + int i;
- +
- + rni = (const struct rt2860_softc_node *) ni;
- +
- + for (i = 0; i < RT2860_SOFTC_RSSI_COUNT; i++)
- + {
- + mi->rssi[i] = rni->last_rssi_dbm[i];
- + mi->noise[i] = RT2860_NOISE_FLOOR;
- + }
- + }
- +
- + /*
- + * rt2860_setregdomain
- + */
- + static int rt2860_setregdomain(struct ieee80211com *ic,
- + struct ieee80211_regdomain *reg,
- + int nchans, struct ieee80211_channel chans[])
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- +
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_STATE,
- + "%s: set regulatory domain: country=%d, country code string=%c%c, location=%c\n",
- + device_get_nameunit(sc->sc_dev),
- + reg->country, reg->isocc[0], reg->isocc[1], reg->location);
- +
- + return 0;
- + }
- +
- + /*
- + * rt2860_getradiocaps
- + */
- + static void rt2860_getradiocaps(struct ieee80211com *ic,
- + int maxchans, int *nchans, struct ieee80211_channel chans[])
- + {
- + *nchans = (ic->ic_nchans >= maxchans) ? maxchans : ic->ic_nchans;
- +
- + memcpy(chans, ic->ic_channels, (*nchans) * sizeof(struct ieee80211_channel));
- + }
- +
- + /*
- + * rt2860_scan_start
- + */
- + static void rt2860_scan_start(struct ieee80211com *ic)
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- +
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- +
- + rt2860_asic_disable_tsf_sync(sc);
- + }
- +
- + /*
- + * rt2860_scan_end
- + */
- + static void rt2860_scan_end(struct ieee80211com *ic)
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- +
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- +
- + rt2860_asic_enable_tsf_sync(sc);
- + }
- +
- + /*
- + * rt2860_set_channel
- + */
- + static void rt2860_set_channel(struct ieee80211com *ic)
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- +
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_CHAN,
- + "%s: set channel: channel=%u, HT%s%s\n",
- + device_get_nameunit(sc->sc_dev),
- + ieee80211_chan2ieee(ic, ic->ic_curchan),
- + !IEEE80211_IS_CHAN_HT(ic->ic_curchan) ? " disabled" :
- + IEEE80211_IS_CHAN_HT20(ic->ic_curchan) ? "20":
- + IEEE80211_IS_CHAN_HT40U(ic->ic_curchan) ? "40U" : "40D",
- + (ic->ic_flags & IEEE80211_F_SCAN) ? ", scanning" : "");
- +
- + RT2860_SOFTC_LOCK(sc);
- +
- + rt2860_rf_set_chan(sc, ic->ic_curchan);
- +
- + RT2860_SOFTC_UNLOCK(sc);
- + }
- +
- + /*
- + * rt2860_newassoc
- + */
- + static void rt2860_newassoc(struct ieee80211_node *ni, int isnew)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct ieee80211vap *vap;
- + struct rt2860_softc_vap *rvap;
- + struct rt2860_softc_node *rni;
- + uint16_t aid;
- + uint8_t wcid;
- + uint32_t tmp;
- +
- + vap = ni->ni_vap;
- + ic = vap->iv_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- + rvap = (struct rt2860_softc_vap *) vap;
- + rni = (struct rt2860_softc_node *) ni;
- +
- + if (isnew)
- + {
- + aid = IEEE80211_AID(ni->ni_associd);
- + rni->staid = rt2860_staid_alloc(sc, aid);
- + wcid = rni->staid;
- +
- + tmp = (ni->ni_macaddr[3] << 24) |
- + (ni->ni_macaddr[2] << 16) |
- + (ni->ni_macaddr[1] << 8) |
- + ni->ni_macaddr[0];
- +
- + rt2860_io_mac_write(sc, RT2860_REG_WCID(wcid), tmp);
- +
- + tmp = (ni->ni_macaddr[5] << 8) |
- + ni->ni_macaddr[4];
- +
- + rt2860_io_mac_write(sc, RT2860_REG_WCID(wcid) + 4, tmp);
- +
- + rt2860_amrr_node_init(&rvap->amrr, &sc->amrr_node[wcid], ni);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_RATE,
- + "%s: initial%s node Tx rate: associd=0x%04x, rate=0x%02x, max rate=0x%02x\n",
- + device_get_nameunit(sc->sc_dev),
- + (ni->ni_flags & IEEE80211_NODE_HT) ? " HT" : "",
- + ni->ni_associd, ni->ni_txrate,
- + (ni->ni_flags & IEEE80211_NODE_HT) ?
- + (ni->ni_htrates.rs_rates[ni->ni_htrates.rs_nrates - 1] | IEEE80211_RATE_MCS) :
- + (ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] & IEEE80211_RATE_VAL));
- +
- + rt2860_asic_updateprot(sc);
- + rt2860_asic_updateslot(sc);
- + rt2860_asic_set_txpreamble(sc);
- + }
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_NODE,
- + "%s: new association: isnew=%d, macaddr=%s, associd=0x%04x, staid=0x%02x, QoS %s, ERP %s, HT %s\n",
- + device_get_nameunit(sc->sc_dev), isnew, ether_sprintf(ni->ni_macaddr),
- + ni->ni_associd, rni->staid,
- + (ni->ni_flags & IEEE80211_NODE_QOS) ? "enabled" : "disabled",
- + (ni->ni_flags & IEEE80211_NODE_ERP) ? "enabled" : "disabled",
- + (ni->ni_flags & IEEE80211_NODE_HT) ? "enabled" : "disabled");
- + }
- +
- + /*
- + * rt2860_updateslot
- + */
- + static void rt2860_updateslot(struct ifnet *ifp)
- + {
- + struct rt2860_softc *sc;
- +
- + sc = ifp->if_softc;
- +
- + rt2860_asic_updateslot(sc);
- + }
- +
- + /*
- + * rt2860_update_promisc
- + */
- + static void rt2860_update_promisc(struct ifnet *ifp)
- + {
- + struct rt2860_softc *sc;
- +
- + sc = ifp->if_softc;
- +
- + rt2860_asic_update_promisc(sc);
- + }
- +
- + /*
- + * rt2860_update_mcast
- + */
- + static void rt2860_update_mcast(struct ifnet *ifp)
- + {
- + struct rt2860_softc *sc;
- +
- + sc = ifp->if_softc;
- + }
- +
- + /*
- + * rt2860_wme_update
- + */
- + static int rt2860_wme_update(struct ieee80211com *ic)
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- +
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- +
- + rt2860_asic_wme_update(sc);
- +
- + return 0;
- + }
- +
- + /*
- + * rt2860_raw_xmit
- + */
- + static int rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
- + const struct ieee80211_bpf_params *params)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- +
- + ic = ni->ni_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- +
- + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- + {
- + m_freem(m);
- + ieee80211_free_node(ni);
- +
- + return ENETDOWN;
- + }
- +
- + RT2860_SOFTC_TX_RING_LOCK(&sc->tx_ring[sc->tx_ring_mgtqid]);
- +
- + if (sc->tx_ring[sc->tx_ring_mgtqid].data_queued >= RT2860_SOFTC_TX_RING_DATA_COUNT)
- + {
- + RT2860_SOFTC_TX_RING_UNLOCK(&sc->tx_ring[sc->tx_ring_mgtqid]);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_TX,
- + "%s: raw xmit: Tx ring with qid=%d is full\n",
- + device_get_nameunit(sc->sc_dev), sc->tx_ring_mgtqid);
- +
- + ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- +
- + m_freem(m);
- + ieee80211_free_node(ni);
- +
- + sc->tx_data_queue_full[sc->tx_ring_mgtqid]++;
- +
- + return ENOBUFS;
- + }
- +
- + if (rt2860_tx_mgmt(sc, m, ni, sc->tx_ring_mgtqid) != 0)
- + {
- + RT2860_SOFTC_TX_RING_UNLOCK(&sc->tx_ring[sc->tx_ring_mgtqid]);
- +
- + ifp->if_oerrors++;
- +
- + ieee80211_free_node(ni);
- +
- + return EIO;
- + }
- +
- + RT2860_SOFTC_TX_RING_UNLOCK(&sc->tx_ring[sc->tx_ring_mgtqid]);
- +
- + sc->sc_tx_timer = RT2860_TX_WATCHDOG_TIMEOUT;
- +
- + return 0;
- + }
- +
- + /*
- + * rt2860_recv_action
- + */
- + static int rt2860_recv_action(struct ieee80211_node *ni,
- + const struct ieee80211_frame *wh,
- + const uint8_t *frm, const uint8_t *efrm)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct rt2860_softc_node *rni;
- + const struct ieee80211_action *ia;
- + uint16_t baparamset;
- + uint8_t wcid;
- + int tid;
- +
- + ic = ni->ni_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- + rni = (struct rt2860_softc_node *) ni;
- +
- + ia = (const struct ieee80211_action *) frm;
- +
- + if (ia->ia_category == IEEE80211_ACTION_CAT_BA)
- + {
- + switch (ia->ia_action)
- + {
- + /* IEEE80211_ACTION_BA_DELBA */
- + case IEEE80211_ACTION_BA_DELBA:
- + baparamset = LE_READ_2(frm + 2);
- + tid = RT2860_MS(baparamset, IEEE80211_BAPS_TID);
- + wcid = rni->staid;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_BA,
- + "%s: received DELBA request: associd=0x%04x, staid=0x%02x, tid=%d\n",
- + device_get_nameunit(sc->sc_dev), ni->ni_associd, rni->staid, tid);
- +
- + if (rni->staid != 0)
- + rt2860_asic_del_ba_session(sc, wcid, tid);
- + break;
- + }
- + }
- +
- + return sc->recv_action(ni, wh, frm, efrm);
- + }
- +
- + /*
- + * rt2860_send_action
- + */
- + static int rt2860_send_action(struct ieee80211_node *ni,
- + int cat, int act, void *sa)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct rt2860_softc_node *rni;
- + uint16_t *args, status, baparamset;
- + uint8_t wcid;
- + int tid, bufsize;
- +
- + ic = ni->ni_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- + rni = (struct rt2860_softc_node *) ni;
- +
- + wcid = rni->staid;
- + args = sa;
- +
- + if (cat == IEEE80211_ACTION_CAT_BA)
- + {
- + switch (act)
- + {
- + /* IEEE80211_ACTION_BA_ADDBA_RESPONSE */
- + case IEEE80211_ACTION_BA_ADDBA_RESPONSE:
- + status = args[1];
- + baparamset = args[2];
- + tid = RT2860_MS(baparamset, IEEE80211_BAPS_TID);
- + bufsize = RT2860_MS(baparamset, IEEE80211_BAPS_BUFSIZ);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_BA,
- + "%s: sending ADDBA response: associd=0x%04x, staid=0x%02x, status=%d, tid=%d, bufsize=%d\n",
- + device_get_nameunit(sc->sc_dev), ni->ni_associd, rni->staid, status, tid, bufsize);
- +
- + if (status == IEEE80211_STATUS_SUCCESS)
- + rt2860_asic_add_ba_session(sc, wcid, tid);
- + break;
- +
- + /* IEEE80211_ACTION_BA_DELBA */
- + case IEEE80211_ACTION_BA_DELBA:
- + baparamset = RT2860_SM(args[0], IEEE80211_DELBAPS_TID) | args[1];
- + tid = RT2860_MS(baparamset, IEEE80211_DELBAPS_TID);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_BA,
- + "%s: sending DELBA request: associd=0x%04x, staid=0x%02x, tid=%d\n",
- + device_get_nameunit(sc->sc_dev), ni->ni_associd, rni->staid, tid);
- +
- + if (RT2860_MS(baparamset, IEEE80211_DELBAPS_INIT) != IEEE80211_DELBAPS_INIT)
- + rt2860_asic_del_ba_session(sc, wcid, tid);
- + break;
- + }
- + }
- +
- + return sc->send_action(ni, cat, act, sa);
- + }
- +
- + /*
- + * rt2860_addba_response
- + */
- + static int rt2860_addba_response(struct ieee80211_node *ni,
- + struct ieee80211_tx_ampdu *tap,
- + int status, int baparamset, int batimeout)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct rt2860_softc_node *rni;
- + ieee80211_seq seqno;
- + int ret, tid, old_bufsize, new_bufsize;
- +
- + ic = ni->ni_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- + rni = (struct rt2860_softc_node *) ni;
- +
- + tid = RT2860_MS(baparamset, IEEE80211_BAPS_TID);
- + old_bufsize = RT2860_MS(baparamset, IEEE80211_BAPS_BUFSIZ);
- + new_bufsize = old_bufsize;
- +
- + if (status == IEEE80211_STATUS_SUCCESS)
- + {
- + if (sc->mac_rev >= 0x28830300)
- + {
- + if (sc->mac_rev >= 0x30700200)
- + new_bufsize = 13;
- + else
- + new_bufsize = 31;
- + }
- + else if (sc->mac_rev >= 0x28720200)
- + {
- + new_bufsize = 13;
- + }
- + else
- + {
- + new_bufsize = 7;
- + }
- +
- + if (old_bufsize > new_bufsize)
- + {
- + baparamset &= ~IEEE80211_BAPS_BUFSIZ;
- + baparamset = RT2860_SM(new_bufsize, IEEE80211_BAPS_BUFSIZ);
- + }
- +
- + if (!(tap->txa_flags & IEEE80211_AGGR_RUNNING))
- + {
- + sc->tx_ampdu_sessions++;
- +
- + if (sc->tx_ampdu_sessions == 1)
- + rt2860_asic_updateprot(sc);
- + }
- + }
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_BA,
- + "%s: received ADDBA response: associd=0x%04x, staid=0x%02x, status=%d, tid=%d, "
- + "old bufsize=%d, new bufsize=%d\n",
- + device_get_nameunit(sc->sc_dev), ni->ni_associd, rni->staid, status, tid,
- + old_bufsize, new_bufsize);
- +
- + ret = sc->addba_response(ni, tap, status, baparamset, batimeout);
- +
- + if (status == IEEE80211_STATUS_SUCCESS)
- + {
- + seqno = ni->ni_txseqs[tid];
- +
- + rt2860_send_bar(ni, tap, seqno);
- + }
- +
- + return ret;
- + }
- +
- + /*
- + * rt2860_addba_stop
- + */
- + static void rt2860_addba_stop(struct ieee80211_node *ni,
- + struct ieee80211_tx_ampdu *tap)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct rt2860_softc_node *rni;
- + int tid;
- +
- + ic = ni->ni_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- + rni = (struct rt2860_softc_node *) ni;
- +
- + tid = WME_AC_TO_TID(tap->txa_ac);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_BA,
- + "%s: stopping A-MPDU Tx: associd=0x%04x, staid=0x%02x, tid=%d\n",
- + device_get_nameunit(sc->sc_dev), ni->ni_associd, rni->staid, tid);
- +
- + if (tap->txa_flags & IEEE80211_AGGR_RUNNING)
- + {
- + if (sc->tx_ampdu_sessions > 0)
- + {
- + sc->tx_ampdu_sessions--;
- +
- + if (sc->tx_ampdu_sessions == 0)
- + rt2860_asic_updateprot(sc);
- + }
- + else
- + {
- + printf("%s: number of A-MPDU Tx sessions cannot be negative\n",
- + device_get_nameunit(sc->sc_dev));
- + }
- + }
- +
- + sc->addba_stop(ni, tap);
- + }
- +
- + /*
- + * rt2860_ampdu_rx_start
- + */
- + static int rt2860_ampdu_rx_start(struct ieee80211_node *ni,
- + struct ieee80211_rx_ampdu *rap,
- + int baparamset, int batimeout, int baseqctl)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct rt2860_softc_node *rni;
- + int tid;
- +
- + ic = ni->ni_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- + rni = (struct rt2860_softc_node *) ni;
- +
- + tid = RT2860_MS(baparamset, IEEE80211_BAPS_TID);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_BA,
- + "%s: starting A-MPDU Rx: associd=0x%04x, staid=0x%02x, tid=%d\n",
- + device_get_nameunit(sc->sc_dev), ni->ni_associd, rni->staid, tid);
- +
- + if (!(rap->rxa_flags & IEEE80211_AGGR_RUNNING))
- + sc->rx_ampdu_sessions++;
- +
- + return sc->ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl);
- + }
- +
- + /*
- + * rt2860_ampdu_rx_stop
- + */
- + static void rt2860_ampdu_rx_stop(struct ieee80211_node *ni,
- + struct ieee80211_rx_ampdu *rap)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct rt2860_softc_node *rni;
- +
- + ic = ni->ni_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- + rni = (struct rt2860_softc_node *) ni;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_BA,
- + "%s: stopping A-MPDU Rx: associd=0x%04x, staid=0x%02x\n",
- + device_get_nameunit(sc->sc_dev), ni->ni_associd, rni->staid);
- +
- + if (rap->rxa_flags & IEEE80211_AGGR_RUNNING)
- + {
- + if (sc->rx_ampdu_sessions > 0)
- + sc->rx_ampdu_sessions--;
- + else
- + printf("%s: number of A-MPDU Rx sessions cannot be negative\n",
- + device_get_nameunit(sc->sc_dev));
- + }
- +
- + sc->ampdu_rx_stop(ni, rap);
- + }
- +
- + /*
- + * rt2860_send_bar
- + */
- + static int rt2860_send_bar(struct ieee80211_node *ni,
- + struct ieee80211_tx_ampdu *tap, ieee80211_seq seqno)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct ieee80211vap *vap;
- + struct ieee80211_frame_bar *bar;
- + struct rt2860_softc_node *rni;
- + struct mbuf *m;
- + uint16_t barctl, barseqctl;
- + uint8_t *frm;
- + int ret, tid;
- +
- + ic = ni->ni_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- + vap = ni->ni_vap;
- + rni = (struct rt2860_softc_node *) ni;
- +
- + if (!(tap->txa_flags & IEEE80211_AGGR_RUNNING))
- + return EINVAL;
- +
- + m = ieee80211_getmgtframe(&frm, ic->ic_headroom, sizeof(struct ieee80211_frame_bar));
- + if (m == NULL)
- + return ENOMEM;
- +
- + bar = mtod(m, struct ieee80211_frame_bar *);
- +
- + bar->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR;
- + bar->i_fc[1] = 0;
- +
- + IEEE80211_ADDR_COPY(bar->i_ra, ni->ni_macaddr);
- + IEEE80211_ADDR_COPY(bar->i_ta, vap->iv_myaddr);
- +
- + tid = WME_AC_TO_TID(tap->txa_ac);
- +
- + barctl = (tap->txa_flags & IEEE80211_AGGR_IMMEDIATE ? 0 : IEEE80211_BAR_NOACK) |
- + IEEE80211_BAR_COMP |
- + RT2860_SM(tid, IEEE80211_BAR_TID);
- + barseqctl = RT2860_SM(seqno, IEEE80211_BAR_SEQ_START);
- +
- + bar->i_ctl = htole16(barctl);
- + bar->i_seq = htole16(barseqctl);
- +
- + m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame_bar);
- +
- + tap->txa_start = seqno;
- +
- + ieee80211_ref_node(ni);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_BA,
- + "%s: sending BAR: associd=0x%04x, staid=0x%02x, tid=%d, seqno=%d\n",
- + device_get_nameunit(sc->sc_dev), ni->ni_associd, rni->staid, tid, seqno);
- +
- + ret = ic->ic_raw_xmit(ni, m, NULL);
- + if (ret != 0)
- + ieee80211_free_node(ni);
- +
- + return ret;
- + }
- +
- + /*
- + * rt2860_amrr_update_iter_func
- + */
- + static void rt2860_amrr_update_iter_func(void *arg, struct ieee80211_node *ni)
- + {
- + struct rt2860_softc *sc;
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + struct ieee80211vap *vap;
- + struct rt2860_softc_vap *rvap;
- + struct rt2860_softc_node *rni;
- + uint8_t wcid;
- +
- + vap = arg;
- + ic = vap->iv_ic;
- + ifp = ic->ic_ifp;
- + sc = ifp->if_softc;
- + rvap = (struct rt2860_softc_vap *) vap;
- + rni = (struct rt2860_softc_node *) ni;
- +
- + /* only associated stations */
- +
- + if ((ni->ni_vap == vap) && (rni->staid != 0))
- + {
- + wcid = rni->staid;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_RATE,
- + "%s: AMRR node: staid=0x%02x, txcnt=%d, success=%d, retrycnt=%d\n",
- + device_get_nameunit(sc->sc_dev),
- + rni->staid, sc->amrr_node[wcid].txcnt, sc->amrr_node[wcid].success, sc->amrr_node[wcid].retrycnt);
- +
- + rt2860_amrr_choose(ni, &sc->amrr_node[wcid]);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_RATE,
- + "%s:%s node Tx rate: associd=0x%04x, staid=0x%02x, rate=0x%02x, max rate=0x%02x\n",
- + device_get_nameunit(sc->sc_dev),
- + (ni->ni_flags & IEEE80211_NODE_HT) ? " HT" : "",
- + ni->ni_associd, rni->staid, ni->ni_txrate,
- + (ni->ni_flags & IEEE80211_NODE_HT) ?
- + (ni->ni_htrates.rs_rates[ni->ni_htrates.rs_nrates - 1] | IEEE80211_RATE_MCS) :
- + (ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] & IEEE80211_RATE_VAL));
- + }
- + }
- +
- + /*
- + * rt2860_periodic
- + */
- + static void rt2860_periodic(void *arg)
- + {
- + struct rt2860_softc *sc;
- +
- + sc = arg;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_PERIODIC,
- + "%s: periodic\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + taskqueue_enqueue(sc->taskqueue, &sc->periodic_task);
- + }
- +
- + /*
- + * rt2860_tx_watchdog
- + */
- + static void rt2860_tx_watchdog(void *arg)
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- +
- + sc = arg;
- + ifp = sc->sc_ifp;
- +
- + if (sc->sc_tx_timer == 0)
- + return;
- +
- + if (--sc->sc_tx_timer == 0)
- + {
- + printf("%s: Tx watchdog timeout: resetting\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + rt2860_stop_locked(sc);
- + rt2860_init_locked(sc);
- +
- + ifp->if_oerrors++;
- +
- + sc->tx_watchdog_timeouts++;
- + }
- +
- + callout_reset(&sc->tx_watchdog_ch, hz, rt2860_tx_watchdog, sc);
- + }
- +
- + /*
- + * rt2860_staid_alloc
- + */
- + static int rt2860_staid_alloc(struct rt2860_softc *sc, int aid)
- + {
- + int staid;
- +
- + if ((aid > 0 && aid < RT2860_SOFTC_STAID_COUNT) && isclr(sc->staid_mask, aid))
- + {
- + staid = aid;
- + }
- + else
- + {
- + for (staid = 1; staid < RT2860_SOFTC_STAID_COUNT; staid++)
- + {
- + if (isclr(sc->staid_mask, staid))
- + break;
- + }
- + }
- +
- + setbit(sc->staid_mask, staid);
- +
- + return staid;
- + }
- +
- + /*
- + * rt2860_staid_delete
- + */
- + static void rt2860_staid_delete(struct rt2860_softc *sc, int staid)
- + {
- + clrbit(sc->staid_mask, staid);
- + }
- +
- + /*
- + * rt2860_asic_set_bssid
- + */
- + static void rt2860_asic_set_bssid(struct rt2860_softc *sc,
- + const uint8_t *bssid)
- + {
- + uint32_t tmp;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_STATE,
- + "%s: set bssid: bssid=%s\n",
- + device_get_nameunit(sc->sc_dev),
- + ether_sprintf(bssid));
- +
- + tmp = bssid[0] | (bssid[1]) << 8 | (bssid[2] << 16) | (bssid[3] << 24);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_BSSID_DW0, tmp);
- +
- + tmp = bssid[4] | (bssid[5] << 8);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_BSSID_DW1, tmp);
- + }
- +
- + /*
- + * rt2860_asic_set_macaddr
- + */
- + static void rt2860_asic_set_macaddr(struct rt2860_softc *sc,
- + const uint8_t *addr)
- + {
- + uint32_t tmp;
- +
- + tmp = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_ADDR_DW0, tmp);
- +
- + tmp = addr[4] | (addr[5] << 8) | (0xff << 16);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_ADDR_DW1, tmp);
- + }
- +
- + /*
- + * rt2860_asic_enable_tsf_sync
- + */
- + static void rt2860_asic_enable_tsf_sync(struct rt2860_softc *sc)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + struct ieee80211vap *vap;
- + uint32_t tmp;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- + vap = TAILQ_FIRST(&ic->ic_vaps);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_BEACON,
- + "%s: enabling TSF\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_BCN_TIME_CFG);
- +
- + tmp &= ~0x1fffff;
- + tmp |= vap->iv_bss->ni_intval * 16;
- + tmp |= (RT2860_REG_TSF_TIMER_ENABLE | RT2860_REG_TBTT_TIMER_ENABLE);
- +
- + if (vap->iv_opmode == IEEE80211_M_STA)
- + {
- + tmp |= (RT2860_REG_TSF_SYNC_MODE_STA << RT2860_REG_TSF_SYNC_MODE_SHIFT);
- + }
- + else if (vap->iv_opmode == IEEE80211_M_IBSS)
- + {
- + tmp |= RT2860_REG_BCN_TX_ENABLE;
- + tmp |= (RT2860_REG_TSF_SYNC_MODE_IBSS << RT2860_REG_TSF_SYNC_MODE_SHIFT);
- + }
- + else if (vap->iv_opmode == IEEE80211_M_HOSTAP)
- + {
- + tmp |= RT2860_REG_BCN_TX_ENABLE;
- + tmp |= (RT2860_REG_TSF_SYNC_MODE_HOSTAP << RT2860_REG_TSF_SYNC_MODE_SHIFT);
- + }
- +
- + rt2860_io_mac_write(sc, RT2860_REG_BCN_TIME_CFG, tmp);
- + }
- +
- + /*
- + * rt2860_asic_disable_tsf_sync
- + */
- + static void rt2860_asic_disable_tsf_sync(struct rt2860_softc *sc)
- + {
- + uint32_t tmp;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_BEACON,
- + "%s: disabling TSF\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_BCN_TIME_CFG);
- +
- + tmp &= ~(RT2860_REG_BCN_TX_ENABLE |
- + RT2860_REG_TSF_TIMER_ENABLE |
- + RT2860_REG_TBTT_TIMER_ENABLE);
- +
- + tmp &= ~(RT2860_REG_TSF_SYNC_MODE_MASK << RT2860_REG_TSF_SYNC_MODE_SHIFT);
- + tmp |= (RT2860_REG_TSF_SYNC_MODE_DISABLE << RT2860_REG_TSF_SYNC_MODE_SHIFT);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_BCN_TIME_CFG, tmp);
- + }
- +
- + /*
- + * rt2860_asic_enable_mrr
- + */
- + static void rt2860_asic_enable_mrr(struct rt2860_softc *sc)
- + {
- + #define CCK(mcs) (mcs)
- + #define OFDM(mcs) ((1 << 3) | (mcs))
- + #define HT(mcs) (mcs)
- +
- + rt2860_io_mac_write(sc, RT2860_REG_TX_LG_FBK_CFG0,
- + (OFDM(6) << 28) | /* 54 -> 48 */
- + (OFDM(5) << 24) | /* 48 -> 36 */
- + (OFDM(4) << 20) | /* 36 -> 24 */
- + (OFDM(3) << 16) | /* 24 -> 18 */
- + (OFDM(2) << 12) | /* 18 -> 12 */
- + (OFDM(1) << 8) | /* 12 -> 9 */
- + (OFDM(0) << 4) | /* 9 -> 6 */
- + OFDM(0)); /* 6 -> 6 */
- +
- + rt2860_io_mac_write(sc, RT2860_REG_TX_LG_FBK_CFG1,
- + (CCK(2) << 12) | /* 11 -> 5.5 */
- + (CCK(1) << 8) | /* 5.5 -> 2 */
- + (CCK(0) << 4) | /* 2 -> 1 */
- + CCK(0)); /* 1 -> 1 */
- +
- + rt2860_io_mac_write(sc, RT2860_REG_TX_HT_FBK_CFG0,
- + (HT(6) << 28) |
- + (HT(5) << 24) |
- + (HT(4) << 20) |
- + (HT(3) << 16) |
- + (HT(2) << 12) |
- + (HT(1) << 8) |
- + (HT(0) << 4) |
- + HT(0));
- +
- + rt2860_io_mac_write(sc, RT2860_REG_TX_HT_FBK_CFG1,
- + (HT(14) << 28) |
- + (HT(13) << 24) |
- + (HT(12) << 20) |
- + (HT(11) << 16) |
- + (HT(10) << 12) |
- + (HT(9) << 8) |
- + (HT(8) << 4) |
- + HT(7));
- +
- + #undef HT
- + #undef OFDM
- + #undef CCK
- + }
- +
- + /*
- + * rt2860_asic_set_txpreamble
- + */
- + static void rt2860_asic_set_txpreamble(struct rt2860_softc *sc)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + uint32_t tmp;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_STATE,
- + "%s: %s short Tx preamble\n",
- + device_get_nameunit(sc->sc_dev),
- + (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? "enabling" : "disabling");
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_AUTO_RSP_CFG);
- +
- + tmp &= ~RT2860_REG_CCK_SHORT_ENABLE;
- +
- + if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
- + tmp |= RT2860_REG_CCK_SHORT_ENABLE;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_AUTO_RSP_CFG, tmp);
- + }
- +
- + /*
- + * rt2860_asic_set_basicrates
- + */
- + static void rt2860_asic_set_basicrates(struct rt2860_softc *sc)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- +
- + if (ic->ic_curmode == IEEE80211_MODE_11B)
- + rt2860_io_mac_write(sc, RT2860_REG_LEGACY_BASIC_RATE, 0xf);
- + else if (ic->ic_curmode == IEEE80211_MODE_11A)
- + rt2860_io_mac_write(sc, RT2860_REG_LEGACY_BASIC_RATE, 0x150);
- + else
- + rt2860_io_mac_write(sc, RT2860_REG_LEGACY_BASIC_RATE, 0x15f);
- + }
- +
- + /*
- + * rt2860_asic_update_rtsthreshold
- + */
- + static void rt2860_asic_update_rtsthreshold(struct rt2860_softc *sc)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + struct ieee80211vap *vap;
- + uint32_t tmp;
- + uint16_t threshold;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- + vap = TAILQ_FIRST(&ic->ic_vaps);
- +
- + if (vap == NULL)
- + threshold = IEEE80211_RTS_MAX;
- + else if (vap->iv_flags_ht & IEEE80211_FHT_AMSDU_TX)
- + threshold = 0x1000;
- + else
- + threshold = vap->iv_rtsthreshold;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_PROT,
- + "%s: updating RTS threshold: %d\n",
- + device_get_nameunit(sc->sc_dev), threshold);
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_TX_RTS_CFG);
- +
- + tmp &= ~(RT2860_REG_TX_RTS_THRESHOLD_MASK << RT2860_REG_TX_RTS_THRESHOLD_SHIFT);
- +
- + tmp |= ((threshold & RT2860_REG_TX_RTS_THRESHOLD_MASK) <<
- + RT2860_REG_TX_RTS_THRESHOLD_SHIFT);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_TX_RTS_CFG, tmp);
- + }
- +
- + /*
- + * rt2860_asic_update_txpower
- + */
- + static void rt2860_asic_update_txpower(struct rt2860_softc *sc)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + uint32_t *txpow_rate;
- + int8_t delta;
- + uint8_t val;
- + uint32_t tmp;
- + int i;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_STATE,
- + "%s: updating Tx power: %d\n",
- + device_get_nameunit(sc->sc_dev), ic->ic_txpowlimit);
- +
- + if (!IEEE80211_IS_CHAN_HT40(ic->ic_curchan))
- + {
- + txpow_rate = sc->txpow_rate_20mhz;
- + }
- + else
- + {
- + if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
- + txpow_rate = sc->txpow_rate_40mhz_2ghz;
- + else
- + txpow_rate = sc->txpow_rate_40mhz_5ghz;
- + }
- +
- + delta = 0;
- +
- + val = rt2860_io_bbp_read(sc, 1);
- + val &= 0xfc;
- +
- + if (ic->ic_txpowlimit > 90)
- + {
- + /* do nothing */
- + }
- + else if (ic->ic_txpowlimit > 60)
- + {
- + delta -= 1;
- + }
- + else if (ic->ic_txpowlimit > 30)
- + {
- + delta -= 3;
- + }
- + else if (ic->ic_txpowlimit > 15)
- + {
- + val |= 0x1;
- + }
- + else if (ic->ic_txpowlimit > 9)
- + {
- + val |= 0x1;
- + delta -= 3;
- + }
- + else
- + {
- + val |= 0x2;
- + }
- +
- + rt2860_io_bbp_write(sc, 1, val);
- +
- + for (i = 0; i < RT2860_SOFTC_TXPOW_RATE_COUNT; i++)
- + {
- + if (txpow_rate[i] == 0xffffffff)
- + continue;
- +
- + tmp = rt2860_read_eeprom_txpow_rate_add_delta(txpow_rate[i], delta);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_TX_PWR_CFG(i), tmp);
- + }
- + }
- +
- + /*
- + * rt2860_asic_update_promisc
- + */
- + static void rt2860_asic_update_promisc(struct rt2860_softc *sc)
- + {
- + struct ifnet *ifp;
- + uint32_t tmp;
- +
- + ifp = sc->sc_ifp;
- +
- + printf("%s: %s promiscuous mode\n",
- + device_get_nameunit(sc->sc_dev),
- + (ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving");
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_RX_FILTER_CFG);
- +
- + tmp &= ~RT2860_REG_RX_FILTER_DROP_UC_NOME;
- +
- + if (!(ifp->if_flags & IFF_PROMISC))
- + tmp |= RT2860_REG_RX_FILTER_DROP_UC_NOME;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_RX_FILTER_CFG, tmp);
- + }
- +
- + /*
- + * rt2860_asic_updateprot
- + */
- + static void rt2860_asic_updateprot(struct rt2860_softc *sc)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + struct ieee80211vap *vap;
- + uint32_t cck_prot, ofdm_prot, mm20_prot, mm40_prot, gf20_prot, gf40_prot;
- + uint8_t htopmode;
- + enum ieee80211_protmode htprotmode;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- + vap = TAILQ_FIRST(&ic->ic_vaps);
- +
- + /* CCK frame protection */
- +
- + cck_prot = RT2860_REG_RTSTH_ENABLE | RT2860_REG_PROT_NAV_SHORT |
- + RT2860_REG_TXOP_ALLOW_ALL | RT2860_REG_PROT_CTRL_NONE;
- +
- + /* set up protection frame phy mode and rate (MCS code) */
- +
- + if (ic->ic_curmode == IEEE80211_MODE_11A)
- + cck_prot |= (RT2860_REG_PROT_PHYMODE_OFDM << RT2860_REG_PROT_PHYMODE_SHIFT) |
- + (0 << RT2860_REG_PROT_MCS_SHIFT);
- + else
- + cck_prot |= ((RT2860_REG_PROT_PHYMODE_CCK << RT2860_REG_PROT_PHYMODE_SHIFT) |
- + (3 << RT2860_REG_PROT_MCS_SHIFT));
- +
- + rt2860_io_mac_write(sc, RT2860_REG_TX_CCK_PROT_CFG, cck_prot);
- +
- + /* OFDM frame protection */
- +
- + ofdm_prot = RT2860_REG_RTSTH_ENABLE | RT2860_REG_PROT_NAV_SHORT |
- + RT2860_REG_TXOP_ALLOW_ALL;
- +
- + if (ic->ic_flags & IEEE80211_F_USEPROT)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_PROT,
- + "%s: updating protection mode: b/g protection mode=%s\n",
- + device_get_nameunit(sc->sc_dev),
- + (ic->ic_protmode == IEEE80211_PROT_RTSCTS) ? "RTS/CTS" :
- + ((ic->ic_protmode == IEEE80211_PROT_CTSONLY) ? "CTS-to-self" : "none"));
- +
- + if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
- + ofdm_prot |= RT2860_REG_PROT_CTRL_RTS_CTS;
- + else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
- + ofdm_prot |= RT2860_REG_PROT_CTRL_CTS;
- + else
- + ofdm_prot |= RT2860_REG_PROT_CTRL_NONE;
- + }
- + else
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_PROT,
- + "%s: updating protection mode: b/g protection mode=%s\n",
- + device_get_nameunit(sc->sc_dev), "none");
- +
- + ofdm_prot |= RT2860_REG_PROT_CTRL_NONE;
- + }
- +
- + rt2860_io_mac_write(sc, RT2860_REG_TX_OFDM_PROT_CFG, ofdm_prot);
- +
- + /* HT frame protection */
- +
- + if ((vap != NULL) && (vap->iv_opmode == IEEE80211_M_STA) && (vap->iv_state == IEEE80211_S_RUN))
- + htopmode = vap->iv_bss->ni_htopmode;
- + else
- + htopmode = ic->ic_curhtprotmode;
- +
- + htprotmode = ic->ic_htprotmode;
- +
- + /* force HT mixed mode and RTS/CTS protection if A-MPDU Tx aggregation is enabled */
- +
- + if (sc->tx_ampdu_sessions > 0)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_PROT,
- + "%s: updating protection mode: forcing HT mixed mode and RTS/CTS protection\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + htopmode = IEEE80211_HTINFO_OPMODE_MIXED;
- + htprotmode = IEEE80211_PROT_RTSCTS;
- + }
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_PROT,
- + "%s: updating protection mode: HT operation mode=0x%02x, protection mode=%s\n",
- + device_get_nameunit(sc->sc_dev),
- + htopmode & IEEE80211_HTINFO_OPMODE,
- + (htprotmode == IEEE80211_PROT_RTSCTS) ? "RTS/CTS" :
- + ((htprotmode == IEEE80211_PROT_CTSONLY) ? "CTS-to-self" : "none"));
- +
- + switch (htopmode & IEEE80211_HTINFO_OPMODE)
- + {
- + /* IEEE80211_HTINFO_OPMODE_HT20PR */
- + case IEEE80211_HTINFO_OPMODE_HT20PR:
- + mm20_prot = RT2860_REG_PROT_NAV_SHORT | RT2860_REG_PROT_CTRL_NONE |
- + RT2860_REG_TXOP_ALLOW_CCK | RT2860_REG_TXOP_ALLOW_OFDM |
- + RT2860_REG_TXOP_ALLOW_MM20 | RT2860_REG_TXOP_ALLOW_GF20 |
- + (RT2860_REG_PROT_PHYMODE_OFDM << RT2860_REG_PROT_PHYMODE_SHIFT) |
- + (4 << RT2860_REG_PROT_MCS_SHIFT);
- +
- + gf20_prot = mm20_prot;
- +
- + mm40_prot = RT2860_REG_PROT_NAV_SHORT | RT2860_REG_TXOP_ALLOW_ALL |
- + (RT2860_REG_PROT_PHYMODE_OFDM << RT2860_REG_PROT_PHYMODE_SHIFT) |
- + (0x84 << RT2860_REG_PROT_MCS_SHIFT);
- +
- + if (htprotmode == IEEE80211_PROT_RTSCTS)
- + mm40_prot |= RT2860_REG_PROT_CTRL_RTS_CTS;
- + else if (htprotmode == IEEE80211_PROT_CTSONLY)
- + mm40_prot |= RT2860_REG_PROT_CTRL_CTS;
- + else
- + mm40_prot |= RT2860_REG_PROT_CTRL_NONE;
- +
- + gf40_prot = mm40_prot;
- + break;
- +
- + /* IEEE80211_HTINFO_OPMODE_MIXED */
- + case IEEE80211_HTINFO_OPMODE_MIXED:
- + mm20_prot = RT2860_REG_PROT_NAV_SHORT |
- + RT2860_REG_TXOP_ALLOW_CCK | RT2860_REG_TXOP_ALLOW_OFDM |
- + RT2860_REG_TXOP_ALLOW_MM20 | RT2860_REG_TXOP_ALLOW_GF20;
- +
- + if (ic->ic_flags & IEEE80211_F_USEPROT)
- + mm20_prot |= (RT2860_REG_PROT_PHYMODE_CCK << RT2860_REG_PROT_PHYMODE_SHIFT) |
- + (3 << RT2860_REG_PROT_MCS_SHIFT);
- + else
- + mm20_prot |= (RT2860_REG_PROT_PHYMODE_OFDM << RT2860_REG_PROT_PHYMODE_SHIFT) |
- + (4 << RT2860_REG_PROT_MCS_SHIFT);
- +
- + if (htprotmode == IEEE80211_PROT_RTSCTS)
- + mm20_prot |= RT2860_REG_PROT_CTRL_RTS_CTS;
- + else if (htprotmode == IEEE80211_PROT_CTSONLY)
- + mm20_prot |= RT2860_REG_PROT_CTRL_CTS;
- + else
- + mm20_prot |= RT2860_REG_PROT_CTRL_NONE;
- +
- + gf20_prot = mm20_prot;
- +
- + mm40_prot = RT2860_REG_PROT_NAV_SHORT | RT2860_REG_TXOP_ALLOW_ALL;
- +
- + if (ic->ic_flags & IEEE80211_F_USEPROT)
- + mm40_prot |= (RT2860_REG_PROT_PHYMODE_CCK << RT2860_REG_PROT_PHYMODE_SHIFT) |
- + (3 << RT2860_REG_PROT_MCS_SHIFT);
- + else
- + mm40_prot |= (RT2860_REG_PROT_PHYMODE_OFDM << RT2860_REG_PROT_PHYMODE_SHIFT) |
- + (0x84 << RT2860_REG_PROT_MCS_SHIFT);
- +
- + if (htprotmode == IEEE80211_PROT_RTSCTS)
- + mm40_prot |= RT2860_REG_PROT_CTRL_RTS_CTS;
- + else if (htprotmode == IEEE80211_PROT_CTSONLY)
- + mm40_prot |= RT2860_REG_PROT_CTRL_CTS;
- + else
- + mm40_prot |= RT2860_REG_PROT_CTRL_NONE;
- +
- + gf40_prot = mm40_prot;
- + break;
- +
- + /*
- + * IEEE80211_HTINFO_OPMODE_PURE
- + * IEEE80211_HTINFO_OPMODE_PROTOPT
- + */
- + case IEEE80211_HTINFO_OPMODE_PURE:
- + case IEEE80211_HTINFO_OPMODE_PROTOPT:
- + default:
- + mm20_prot = RT2860_REG_PROT_NAV_SHORT | RT2860_REG_PROT_CTRL_NONE |
- + RT2860_REG_TXOP_ALLOW_CCK | RT2860_REG_TXOP_ALLOW_OFDM |
- + RT2860_REG_TXOP_ALLOW_MM20 | RT2860_REG_TXOP_ALLOW_GF20 |
- + (RT2860_REG_PROT_PHYMODE_OFDM << RT2860_REG_PROT_PHYMODE_SHIFT) |
- + (4 << RT2860_REG_PROT_MCS_SHIFT);
- +
- + gf20_prot = mm20_prot;
- +
- + mm40_prot = RT2860_REG_PROT_NAV_SHORT | RT2860_REG_PROT_CTRL_NONE |
- + RT2860_REG_TXOP_ALLOW_ALL |
- + (RT2860_REG_PROT_PHYMODE_OFDM << RT2860_REG_PROT_PHYMODE_SHIFT) |
- + (0x84 << RT2860_REG_PROT_MCS_SHIFT);
- +
- + gf40_prot = mm40_prot;
- + break;
- + }
- +
- + rt2860_io_mac_write(sc, RT2860_REG_TX_MM20_PROT_CFG, mm20_prot);
- + rt2860_io_mac_write(sc, RT2860_REG_TX_MM40_PROT_CFG, mm40_prot);
- + rt2860_io_mac_write(sc, RT2860_REG_TX_GF20_PROT_CFG, gf20_prot);
- + rt2860_io_mac_write(sc, RT2860_REG_TX_GF40_PROT_CFG, gf40_prot);
- + }
- +
- + /*
- + * rt2860_asic_updateslot
- + */
- + static void rt2860_asic_updateslot(struct rt2860_softc *sc)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + struct ieee80211vap *vap;
- + uint32_t tmp;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- + vap = TAILQ_FIRST(&ic->ic_vaps);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_STATE,
- + "%s: %s short slot time\n",
- + device_get_nameunit(sc->sc_dev),
- + ((ic->ic_flags & IEEE80211_F_SHSLOT) ||
- + ((vap != NULL) && (vap->iv_flags & IEEE80211_F_BURST))) ? "enabling" : "disabling");
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_BKOFF_SLOT_CFG);
- +
- + tmp &= ~0xff;
- +
- + if ((ic->ic_flags & IEEE80211_F_SHSLOT) ||
- + ((vap != NULL) && (vap->iv_flags & IEEE80211_F_BURST)))
- + tmp |= IEEE80211_DUR_SHSLOT;
- + else
- + tmp |= IEEE80211_DUR_SLOT;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_BKOFF_SLOT_CFG, tmp);
- + }
- +
- + /*
- + * rt2860_asic_wme_update
- + */
- + static void rt2860_asic_wme_update(struct rt2860_softc *sc)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + struct ieee80211_wme_state *wme;
- + const struct wmeParams *wmep;
- + int i;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- + wme = &ic->ic_wme;
- + wmep = wme->wme_chanParams.cap_wmeParams;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_WME,
- + "%s: wme update: WME_AC_VO=%d/%d/%d/%d, WME_AC_VI=%d/%d/%d/%d, "
- + "WME_AC_BK=%d/%d/%d/%d, WME_AC_BE=%d/%d/%d/%d\n",
- + device_get_nameunit(sc->sc_dev),
- + wmep[WME_AC_VO].wmep_aifsn,
- + wmep[WME_AC_VO].wmep_logcwmin, wmep[WME_AC_VO].wmep_logcwmax,
- + wmep[WME_AC_VO].wmep_txopLimit,
- + wmep[WME_AC_VI].wmep_aifsn,
- + wmep[WME_AC_VI].wmep_logcwmin, wmep[WME_AC_VI].wmep_logcwmax,
- + wmep[WME_AC_VI].wmep_txopLimit,
- + wmep[WME_AC_BK].wmep_aifsn,
- + wmep[WME_AC_BK].wmep_logcwmin, wmep[WME_AC_BK].wmep_logcwmax,
- + wmep[WME_AC_BK].wmep_txopLimit,
- + wmep[WME_AC_BE].wmep_aifsn,
- + wmep[WME_AC_BE].wmep_logcwmin, wmep[WME_AC_BE].wmep_logcwmax,
- + wmep[WME_AC_BE].wmep_txopLimit);
- +
- + for (i = 0; i < WME_NUM_AC; i++)
- + rt2860_io_mac_write(sc, RT2860_REG_TX_EDCA_AC_CFG(i),
- + (wmep[i].wmep_logcwmax << 16) | (wmep[i].wmep_logcwmin << 12) |
- + (wmep[i].wmep_aifsn << 8) | wmep[i].wmep_txopLimit);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WMM_AIFSN_CFG,
- + (wmep[WME_AC_VO].wmep_aifsn << 12) | (wmep[WME_AC_VI].wmep_aifsn << 8) |
- + (wmep[WME_AC_BK].wmep_aifsn << 4) | wmep[WME_AC_BE].wmep_aifsn);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WMM_CWMIN_CFG,
- + (wmep[WME_AC_VO].wmep_logcwmin << 12) | (wmep[WME_AC_VI].wmep_logcwmin << 8) |
- + (wmep[WME_AC_BK].wmep_logcwmin << 4) | wmep[WME_AC_BE].wmep_logcwmin);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WMM_CWMAX_CFG,
- + (wmep[WME_AC_VO].wmep_logcwmax << 12) | (wmep[WME_AC_VI].wmep_logcwmax << 8) |
- + (wmep[WME_AC_BK].wmep_logcwmax << 4) | wmep[WME_AC_BE].wmep_logcwmax);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WMM_TXOP0_CFG,
- + (wmep[WME_AC_BK].wmep_txopLimit << 16) | wmep[WME_AC_BE].wmep_txopLimit);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WMM_TXOP1_CFG,
- + (wmep[WME_AC_VO].wmep_txopLimit << 16) | wmep[WME_AC_VI].wmep_txopLimit);
- + }
- +
- + /*
- + * rt2860_asic_update_beacon
- + */
- + static void rt2860_asic_update_beacon(struct rt2860_softc *sc,
- + struct ieee80211vap *vap)
- + {
- + struct rt2860_softc_vap *rvap;
- + struct mbuf *m;
- + struct rt2860_txwi *txwi;
- + uint32_t tmp;
- +
- + rvap = (struct rt2860_softc_vap *) vap;
- +
- + m = rvap->beacon_mbuf;
- + txwi = &rvap->beacon_txwi;
- +
- + /* disable temporarily TSF sync */
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_BCN_TIME_CFG);
- +
- + tmp &= ~(RT2860_REG_BCN_TX_ENABLE |
- + RT2860_REG_TSF_TIMER_ENABLE |
- + RT2860_REG_TBTT_TIMER_ENABLE);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_BCN_TIME_CFG, tmp);
- +
- + /* write Tx wireless info and beacon frame to on-chip memory */
- +
- + rt2860_io_mac_write_multi(sc, RT2860_REG_BEACON_BASE(0),
- + txwi, sizeof(struct rt2860_txwi));
- +
- + rt2860_io_mac_write_multi(sc, RT2860_REG_BEACON_BASE(0) + sizeof(struct rt2860_txwi),
- + mtod(m, uint8_t *), m->m_pkthdr.len);
- +
- + /* enable again TSF sync */
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_BCN_TIME_CFG);
- +
- + tmp |= (RT2860_REG_BCN_TX_ENABLE |
- + RT2860_REG_TSF_TIMER_ENABLE |
- + RT2860_REG_TBTT_TIMER_ENABLE);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_BCN_TIME_CFG, tmp);
- + }
- +
- + /*
- + * rt2860_asic_clear_keytables
- + */
- + static void rt2860_asic_clear_keytables(struct rt2860_softc *sc)
- + {
- + int i;
- +
- + /* clear Rx WCID search table (entries = 256, entry size = 8) */
- +
- + for (i = 0; i < 256; i++)
- + {
- + rt2860_io_mac_write(sc, RT2860_REG_WCID(i), 0xffffffff);
- + rt2860_io_mac_write(sc, RT2860_REG_WCID(i) + 4, 0x0000ffff);
- + }
- +
- + /* clear WCID attribute table (entries = 256, entry size = 4) */
- +
- + rt2860_io_mac_set_region_4(sc, RT2860_REG_WCID_ATTR(0), 0, 256);
- +
- + /* clear IV/EIV table (entries = 256, entry size = 8) */
- +
- + rt2860_io_mac_set_region_4(sc, RT2860_REG_IVEIV(0), 0, 2 * 256);
- +
- + /* clear pairwise key table (entries = 64, entry size = 32) */
- +
- + rt2860_io_mac_set_region_4(sc, RT2860_REG_PKEY(0), 0, 8 * 64);
- +
- + /* clear shared key table (entries = 32, entry size = 32) */
- +
- + rt2860_io_mac_set_region_4(sc, RT2860_REG_SKEY(0, 0), 0, 8 * 32);
- +
- + /* clear shared key mode (entries = 32, entry size = 2) */
- +
- + rt2860_io_mac_set_region_4(sc, RT2860_REG_SKEY_MODE(0), 0, 16);
- + }
- +
- + /*
- + * rt2860_asic_add_ba_session
- + */
- + static void rt2860_asic_add_ba_session(struct rt2860_softc *sc,
- + uint8_t wcid, int tid)
- + {
- + uint32_t tmp;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_BA,
- + "%s: adding BA session: wcid=0x%02x, tid=%d\n",
- + device_get_nameunit(sc->sc_dev), wcid, tid);
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_WCID(wcid) + 4);
- +
- + tmp |= (0x10000 << tid);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_WCID(wcid) + 4, tmp);
- + }
- +
- + /*
- + * rt2860_asic_del_ba_session
- + */
- + static void rt2860_asic_del_ba_session(struct rt2860_softc *sc,
- + uint8_t wcid, int tid)
- + {
- + uint32_t tmp;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_BA,
- + "%s: deleting BA session: wcid=0x%02x, tid=%d\n",
- + device_get_nameunit(sc->sc_dev), wcid, tid);
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_WCID(wcid) + 4);
- +
- + tmp &= ~(0x10000 << tid);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_WCID(wcid) + 4, tmp);
- + }
- +
- + /*
- + * rt2860_beacon_alloc
- + */
- + static int rt2860_beacon_alloc(struct rt2860_softc *sc,
- + struct ieee80211vap *vap)
- + {
- + struct ieee80211com *ic;
- + struct rt2860_softc_vap *rvap;
- + struct mbuf *m;
- + struct rt2860_txwi txwi;
- + uint8_t rate, mcs;
- +
- + ic = vap->iv_ic;
- + rvap = (struct rt2860_softc_vap *) vap;
- +
- + m = ieee80211_beacon_alloc(vap->iv_bss, &rvap->beacon_offsets);
- + if (m == NULL)
- + return ENOMEM;
- +
- + rate = IEEE80211_IS_CHAN_5GHZ(vap->iv_bss->ni_chan) ? 12 : 2;
- + mcs = rt2860_rate2mcs(rate);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_BEACON,
- + "%s: beacon allocate: mcs=0x%02x\n",
- + device_get_nameunit(sc->sc_dev), mcs);
- +
- + memset(&txwi, 0, sizeof(struct rt2860_txwi));
- +
- + txwi.wcid = RT2860_WCID_RESERVED;
- + txwi.pid_mpdu_len = ((htole16(m->m_pkthdr.len) & RT2860_TXWI_MPDU_LEN_MASK) <<
- + RT2860_TXWI_MPDU_LEN_SHIFT);
- + txwi.txop = (RT2860_TXWI_TXOP_HT << RT2860_TXWI_TXOP_SHIFT);
- + txwi.mpdu_density_flags |=
- + (RT2860_TXWI_FLAGS_TS << RT2860_TXWI_FLAGS_SHIFT);
- + txwi.bawin_size_xflags |=
- + (RT2860_TXWI_XFLAGS_NSEQ << RT2860_TXWI_XFLAGS_SHIFT);
- +
- + if (rate == 2)
- + {
- + txwi.phymode_ifs_stbc_shortgi =
- + (RT2860_TXWI_PHYMODE_CCK << RT2860_TXWI_PHYMODE_SHIFT);
- +
- + if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
- + mcs |= RT2860_TXWI_MCS_SHOTPRE;
- + }
- + else
- + {
- + txwi.phymode_ifs_stbc_shortgi =
- + (RT2860_TXWI_PHYMODE_OFDM << RT2860_TXWI_PHYMODE_SHIFT);
- + }
- +
- + txwi.bw_mcs = (RT2860_TXWI_BW_20 << RT2860_TXWI_BW_SHIFT) |
- + ((mcs & RT2860_TXWI_MCS_MASK) << RT2860_TXWI_MCS_SHIFT);
- +
- + if (rvap->beacon_mbuf != NULL)
- + {
- + m_free(rvap->beacon_mbuf);
- + rvap->beacon_mbuf = NULL;
- + }
- +
- + rvap->beacon_mbuf = m;
- + rvap->beacon_txwi = txwi;
- +
- + return 0;
- + }
- +
- + /*
- + * rt2860_rxrate
- + */
- + static uint8_t rt2860_rxrate(struct rt2860_rxwi *rxwi)
- + {
- + uint8_t mcs, phymode;
- + uint8_t rate;
- +
- + mcs = (rxwi->bw_mcs >> RT2860_RXWI_MCS_SHIFT) & RT2860_RXWI_MCS_MASK;
- + phymode = (rxwi->phymode_stbc_shortgi >> RT2860_RXWI_PHYMODE_SHIFT) &
- + RT2860_RXWI_PHYMODE_MASK;
- +
- + rate = 2;
- +
- + switch (phymode)
- + {
- + case RT2860_RXWI_PHYMODE_CCK:
- + switch (mcs & ~RT2860_RXWI_MCS_SHOTPRE)
- + {
- + case 0: rate = 2; break; /* 1 Mbps */
- + case 1: rate = 4; break; /* 2 MBps */
- + case 2: rate = 11; break; /* 5.5 Mbps */
- + case 3: rate = 22; break; /* 11 Mbps */
- + }
- + break;
- +
- + case RT2860_RXWI_PHYMODE_OFDM:
- + switch (mcs)
- + {
- + case 0: rate = 12; break; /* 6 Mbps */
- + case 1: rate = 18; break; /* 9 Mbps */
- + case 2: rate = 24; break; /* 12 Mbps */
- + case 3: rate = 36; break; /* 18 Mbps */
- + case 4: rate = 48; break; /* 24 Mbps */
- + case 5: rate = 72; break; /* 36 Mbps */
- + case 6: rate = 96; break; /* 48 Mbps */
- + case 7: rate = 108; break; /* 54 Mbps */
- + }
- + break;
- +
- + case RT2860_RXWI_PHYMODE_HT_MIXED:
- + case RT2860_RXWI_PHYMODE_HT_GF:
- + break;
- + }
- +
- + return rate;
- + }
- +
- + /*
- + * rt2860_maxrssi_rxpath
- + */
- + static uint8_t rt2860_maxrssi_rxpath(struct rt2860_softc *sc,
- + const struct rt2860_rxwi *rxwi)
- + {
- + uint8_t rxpath;
- +
- + rxpath = 0;
- +
- + if (sc->nrxpath > 1)
- + if (rxwi->rssi[1] > rxwi->rssi[rxpath])
- + rxpath = 1;
- +
- + if (sc->nrxpath > 2)
- + if (rxwi->rssi[2] > rxwi->rssi[rxpath])
- + rxpath = 2;
- +
- + return rxpath;
- + }
- +
- + /*
- + * rt2860_rssi2dbm
- + */
- + static int8_t rt2860_rssi2dbm(struct rt2860_softc *sc,
- + uint8_t rssi, uint8_t rxpath)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + struct ieee80211_channel *c;
- + int chan;
- + int8_t rssi_off, lna_gain;
- +
- + if (rssi == 0)
- + return -99;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- + c = ic->ic_curchan;
- + chan = ieee80211_chan2ieee(ic, c);
- +
- + if (IEEE80211_IS_CHAN_5GHZ(c))
- + {
- + rssi_off = sc->rssi_off_5ghz[rxpath];
- +
- + if (chan <= 64)
- + lna_gain = sc->lna_gain[1];
- + else if (chan <= 128)
- + lna_gain = sc->lna_gain[2];
- + else
- + lna_gain = sc->lna_gain[3];
- + }
- + else
- + {
- + rssi_off = sc->rssi_off_2ghz[rxpath] - sc->lna_gain[0];
- + lna_gain = sc->lna_gain[0];
- + }
- +
- + return (-12 - rssi_off - lna_gain - rssi);
- + }
- +
- + /*
- + * rt2860_rate2mcs
- + */
- + static uint8_t rt2860_rate2mcs(uint8_t rate)
- + {
- + switch (rate)
- + {
- + /* CCK rates */
- + case 2: return 0;
- + case 4: return 1;
- + case 11: return 2;
- + case 22: return 3;
- +
- + /* OFDM rates */
- + case 12: return 0;
- + case 18: return 1;
- + case 24: return 2;
- + case 36: return 3;
- + case 48: return 4;
- + case 72: return 5;
- + case 96: return 6;
- + case 108: return 7;
- + }
- +
- + return 0;
- + }
- +
- + /*
- + * rt2860_tx_mgmt
- + */
- + static int rt2860_tx_mgmt(struct rt2860_softc *sc,
- + struct mbuf *m, struct ieee80211_node *ni, int qid)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + struct ieee80211vap *vap;
- + const struct ieee80211_txparam *tp;
- + struct rt2860_softc_node *rni;
- + struct rt2860_softc_tx_ring *ring;
- + struct rt2860_softc_tx_data *data;
- + struct rt2860_txdesc *desc;
- + struct rt2860_txwi *txwi;
- + struct ieee80211_frame *wh;
- + struct rt2860_softc_tx_radiotap_header *tap;
- + bus_dma_segment_t dma_seg[RT2860_SOFTC_MAX_SCATTER];
- + u_int hdrsize, hdrspace;
- + uint8_t rate, mcs, pid, qsel;
- + uint16_t len, dmalen, mpdu_len, dur;
- + int error, mimops, ndmasegs, ndescs, i, j;
- +
- + KASSERT(qid >= 0 && qid < RT2860_SOFTC_TX_RING_COUNT,
- + ("%s: Tx MGMT: invalid qid=%d\n",
- + device_get_nameunit(sc->sc_dev), qid));
- +
- + RT2860_SOFTC_TX_RING_ASSERT_LOCKED(&sc->tx_ring[qid]);
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- + vap = ni->ni_vap;
- + rni = (struct rt2860_softc_node *) ni;
- + tp = ni->ni_txparms;
- +
- + ring = &sc->tx_ring[qid];
- + desc = &ring->desc[ring->desc_cur];
- + data = &ring->data[ring->data_cur];
- + txwi = (struct rt2860_txwi *) (ring->seg0 + ring->data_cur * RT2860_TX_DATA_SEG0_SIZE);
- +
- + wh = mtod(m, struct ieee80211_frame *);
- +
- + rate = tp->mgmtrate & IEEE80211_RATE_VAL;
- + /* XXX */
- + if (!rate)
- + return EFBIG;
- +
- + /* fill Tx wireless info */
- +
- + if (ni->ni_flags & IEEE80211_NODE_HT)
- + mcs = rate;
- + else
- + mcs = rt2860_rate2mcs(rate);
- +
- + /* calculate MPDU length without padding */
- +
- + hdrsize = ieee80211_anyhdrsize(wh);
- + hdrspace = ieee80211_anyhdrspace(ic, wh);
- + mpdu_len = m->m_pkthdr.len - hdrspace + hdrsize;
- +
- + memset(txwi, 0, sizeof(struct rt2860_txwi));
- +
- + /* management frames do not need encryption */
- +
- + txwi->wcid = RT2860_WCID_RESERVED;
- +
- + /* MIMO power save */
- +
- + if ((ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_flags & IEEE80211_NODE_MIMO_PS))
- + {
- + if (mcs > 7)
- + {
- + if (ni->ni_flags & IEEE80211_NODE_MIMO_RTS)
- + {
- + /* dynamic MIMO power save */
- +
- + txwi->mpdu_density_flags |=
- + (RT2860_TXWI_FLAGS_MIMOPS << RT2860_TXWI_FLAGS_SHIFT);
- + }
- + else
- + {
- + /* static MIMO power save */
- +
- + mcs = 7;
- + }
- + }
- +
- + mimops = 1;
- + }
- + else
- + {
- + mimops = 0;
- + }
- +
- + pid = (mcs < 0xf) ? (mcs + 1) : mcs;
- +
- + txwi->pid_mpdu_len = ((htole16(pid) & RT2860_TXWI_PID_MASK) <<
- + RT2860_TXWI_PID_SHIFT) | ((htole16(mpdu_len) & RT2860_TXWI_MPDU_LEN_MASK) <<
- + RT2860_TXWI_MPDU_LEN_SHIFT);
- +
- + if (ni->ni_flags & IEEE80211_NODE_HT)
- + {
- + txwi->phymode_ifs_stbc_shortgi |=
- + (RT2860_TXWI_PHYMODE_HT_MIXED << RT2860_TXWI_PHYMODE_SHIFT);
- + }
- + else
- + {
- + if (ieee80211_rate2phytype(ic->ic_rt, rate) != IEEE80211_T_OFDM)
- + {
- + txwi->phymode_ifs_stbc_shortgi |=
- + (RT2860_TXWI_PHYMODE_CCK << RT2860_TXWI_PHYMODE_SHIFT);
- +
- + if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
- + mcs |= RT2860_TXWI_MCS_SHOTPRE;
- + }
- + else
- + {
- + txwi->phymode_ifs_stbc_shortgi |=
- + (RT2860_TXWI_PHYMODE_OFDM << RT2860_TXWI_PHYMODE_SHIFT);
- + }
- + }
- +
- + txwi->bw_mcs = (RT2860_TXWI_BW_20 << RT2860_TXWI_BW_SHIFT) |
- + ((mcs & RT2860_TXWI_MCS_MASK) << RT2860_TXWI_MCS_SHIFT);
- +
- + txwi->txop = (RT2860_TXWI_TXOP_BACKOFF << RT2860_TXWI_TXOP_SHIFT);
- +
- + /* skip ACKs for multicast frames */
- +
- + if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
- + {
- + txwi->bawin_size_xflags |=
- + (RT2860_TXWI_XFLAGS_ACK << RT2860_TXWI_XFLAGS_SHIFT);
- +
- + if (ni->ni_flags & IEEE80211_NODE_HT)
- + {
- + /* preamble + plcp + signal extension + SIFS */
- +
- + dur = 16 + 4 + 6 + 10;
- + }
- + else
- + {
- + dur = ieee80211_ack_duration(ic->ic_rt, rate,
- + ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- + }
- +
- + *(uint16_t *) wh->i_dur = htole16(dur);
- + }
- +
- + /* ask MAC to insert timestamp into probe responses */
- +
- + if ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
- + (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
- + txwi->mpdu_density_flags |=
- + (RT2860_TXWI_FLAGS_TS << RT2860_TXWI_FLAGS_SHIFT);
- +
- + if (ieee80211_radiotap_active_vap(vap))
- + {
- + tap = &sc->txtap;
- +
- + tap->flags = IEEE80211_RADIOTAP_F_DATAPAD;
- + tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
- + tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
- + tap->chan_ieee = ic->ic_curchan->ic_ieee;
- + tap->chan_maxpow = 0;
- +
- + if (ni->ni_flags & IEEE80211_NODE_HT)
- + tap->rate = mcs | IEEE80211_RATE_MCS;
- + else
- + tap->rate = rate;
- +
- + if (mcs & RT2860_TXWI_MCS_SHOTPRE)
- + tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
- +
- + if (wh->i_fc[1] & IEEE80211_FC1_WEP)
- + tap->flags |= IEEE80211_RADIOTAP_F_WEP;
- +
- + if (wh->i_fc[1] & IEEE80211_FC1_WEP)
- + {
- + wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
- +
- + ieee80211_radiotap_tx(vap, m);
- +
- + wh->i_fc[1] |= IEEE80211_FC1_WEP;
- + }
- + else
- + {
- + ieee80211_radiotap_tx(vap, m);
- + }
- + }
- +
- + /* copy and trim 802.11 header */
- +
- + m_copydata(m, 0, hdrsize, (caddr_t) (txwi + 1));
- + m_adj(m, hdrspace);
- +
- + error = bus_dmamap_load_mbuf_sg(ring->data_dma_tag, data->dma_map, m,
- + dma_seg, &ndmasegs, BUS_DMA_NOWAIT);
- + if (error != 0)
- + {
- + /* too many fragments, linearize */
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_TX,
- + "%s: could not load mbuf DMA map, trying to linearize mbuf: ndmasegs=%d, len=%d, error=%d\n",
- + device_get_nameunit(sc->sc_dev), ndmasegs, m->m_pkthdr.len, error);
- +
- + m = m_defrag(m, M_DONTWAIT);
- + if (m == NULL)
- + return ENOMEM;
- +
- + sc->tx_defrag_packets++;
- +
- + error = bus_dmamap_load_mbuf_sg(ring->data_dma_tag, data->dma_map, m,
- + dma_seg, &ndmasegs, BUS_DMA_NOWAIT);
- + if (error != 0)
- + {
- + printf("%s: could not load mbuf DMA map: ndmasegs=%d, len=%d, error=%d\n",
- + device_get_nameunit(sc->sc_dev), ndmasegs, m->m_pkthdr.len, error);
- + m_freem(m);
- + return error;
- + }
- + }
- +
- + if (m->m_pkthdr.len == 0)
- + ndmasegs = 0;
- +
- + /* determine how many Tx descs are required */
- +
- + ndescs = 1 + ndmasegs / 2;
- + if ((ring->desc_queued + ndescs) > (RT2860_SOFTC_TX_RING_DESC_COUNT - 2))
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_TX,
- + "%s: there are not enough Tx descs\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->no_tx_desc_avail++;
- +
- + bus_dmamap_unload(ring->data_dma_tag, data->dma_map);
- + m_freem(m);
- + return EFBIG;
- + }
- +
- + data->m = m;
- + data->ni = ni;
- +
- + /* set up Tx descs */
- +
- + /* first segment is Tx wireless info and 802.11 header */
- +
- + len = sizeof(struct rt2860_txwi) + hdrsize;
- +
- + /* align end on a 4-bytes boundary */
- +
- + dmalen = (len + 3) & ~ 3;
- +
- + memset((caddr_t) txwi + len, 0, dmalen - len);
- +
- + qsel = RT2860_TXDESC_QSEL_EDCA;
- +
- + desc->sdp0 = htole32(ring->seg0_phys_addr + ring->data_cur * RT2860_TX_DATA_SEG0_SIZE);
- + desc->sdl0 = htole16(dmalen);
- + desc->qsel_flags = (qsel << RT2860_TXDESC_QSEL_SHIFT);
- +
- + /* set up payload segments */
- +
- + for (i = ndmasegs, j = 0; i >= 2; i -= 2)
- + {
- + desc->sdp1 = htole32(dma_seg[j].ds_addr);
- + desc->sdl1 = htole16(dma_seg[j].ds_len);
- +
- + ring->desc_queued++;
- + ring->desc_cur = (ring->desc_cur + 1) % RT2860_SOFTC_TX_RING_DESC_COUNT;
- +
- + j++;
- +
- + desc = &ring->desc[ring->desc_cur];
- +
- + desc->sdp0 = htole32(dma_seg[j].ds_addr);
- + desc->sdl0 = htole16(dma_seg[j].ds_len);
- + desc->qsel_flags = (qsel << RT2860_TXDESC_QSEL_SHIFT);
- +
- + j++;
- + }
- +
- + /* finalize last payload segment */
- +
- + if (i > 0)
- + {
- + desc->sdp1 = htole32(dma_seg[j].ds_addr);
- + desc->sdl1 = htole16(dma_seg[j].ds_len | RT2860_TXDESC_SDL1_LASTSEG);
- + }
- + else
- + {
- + desc->sdl0 |= htole16(RT2860_TXDESC_SDL0_LASTSEG);
- + desc->sdl1 = 0;
- + }
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_TX,
- + "%s: sending MGMT frame: qid=%d, hdrsize=%d, hdrspace=%d, len=%d, "
- + "mcs=%d, mimops=%d, DMA len=%d, ndmasegs=%d, DMA ds_len=%d/%d/%d/%d/%d\n",
- + device_get_nameunit(sc->sc_dev),
- + qid, hdrsize, hdrspace, m->m_pkthdr.len + hdrsize,
- + mcs, mimops, dmalen, ndmasegs,
- + (int) dma_seg[0].ds_len, (int) dma_seg[1].ds_len, (int) dma_seg[2].ds_len, (int) dma_seg[3].ds_len, (int) dma_seg[4].ds_len);
- +
- + bus_dmamap_sync(ring->seg0_dma_tag, ring->seg0_dma_map,
- + BUS_DMASYNC_PREWRITE);
- + bus_dmamap_sync(ring->data_dma_tag, data->dma_map,
- + BUS_DMASYNC_PREWRITE);
- + bus_dmamap_sync(ring->desc_dma_tag, ring->desc_dma_map,
- + BUS_DMASYNC_PREWRITE);
- +
- + ring->desc_queued++;
- + ring->desc_cur = (ring->desc_cur + 1) % RT2860_SOFTC_TX_RING_DESC_COUNT;
- +
- + ring->data_queued++;
- + ring->data_cur = (ring->data_cur + 1) % RT2860_SOFTC_TX_RING_DATA_COUNT;
- +
- + /* kick Tx */
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_TX_CTX_IDX(qid), ring->desc_cur);
- +
- + return 0;
- + }
- +
- + /*
- + * rt2860_tx_data
- + */
- + static int rt2860_tx_data(struct rt2860_softc *sc,
- + struct mbuf *m, struct ieee80211_node *ni, int qid)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + struct ieee80211vap *vap;
- + const struct ieee80211_txparam *tp;
- + struct rt2860_softc_node *rni;
- + struct rt2860_softc_tx_ring *ring;
- + struct rt2860_softc_tx_data *data;
- + struct rt2860_txdesc *desc;
- + struct rt2860_txwi *txwi;
- + struct ieee80211_frame *wh;
- + struct ieee80211_tx_ampdu *tx_ampdu;
- + ieee80211_seq seqno;
- + struct rt2860_softc_tx_radiotap_header *tap;
- + bus_dma_segment_t dma_seg[RT2860_SOFTC_MAX_SCATTER];
- + u_int hdrsize, hdrspace;
- + uint8_t type, rate, bw, stbc, shortgi, mcs, pid, wcid, mpdu_density, bawin_size, qsel;
- + uint16_t qos, len, dmalen, mpdu_len, dur;
- + int error, hasqos, ac, tid, ampdu, mimops, ndmasegs, ndescs, i, j;
- +
- + KASSERT(qid >= 0 && qid < RT2860_SOFTC_TX_RING_COUNT,
- + ("%s: Tx data: invalid qid=%d\n",
- + device_get_nameunit(sc->sc_dev), qid));
- +
- + RT2860_SOFTC_TX_RING_ASSERT_LOCKED(&sc->tx_ring[qid]);
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- + vap = ni->ni_vap;
- + rni = (struct rt2860_softc_node *) ni;
- + tp = ni->ni_txparms;
- +
- + ring = &sc->tx_ring[qid];
- + desc = &ring->desc[ring->desc_cur];
- + data = &ring->data[ring->data_cur];
- + txwi = (struct rt2860_txwi *) (ring->seg0 + ring->data_cur * RT2860_TX_DATA_SEG0_SIZE);
- +
- + wh = mtod(m, struct ieee80211_frame *);
- +
- + type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
- +
- + hasqos = IEEE80211_QOS_HAS_SEQ(wh);
- + if (hasqos)
- + {
- + if (IEEE80211_HAS_ADDR4(wh))
- + qos = le16toh(*(const uint16_t *)
- + (((struct ieee80211_qosframe_addr4 *) wh)->i_qos));
- + else
- + qos = le16toh(*(const uint16_t *)
- + (((struct ieee80211_qosframe *) wh)->i_qos));
- + }
- + else
- + {
- + qos = 0;
- + }
- +
- + if (IEEE80211_IS_MULTICAST(wh->i_addr1))
- + rate = tp->mcastrate;
- + else if (m->m_flags & M_EAPOL)
- + rate = tp->mgmtrate;
- + else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
- + rate = tp->ucastrate;
- + else
- + rate = ni->ni_txrate;
- +
- + rate &= IEEE80211_RATE_VAL;
- + /* XXX */
- + if (!rate)
- + return EFBIG;
- +
- + /* fill Tx wireless info */
- +
- + if (ni->ni_flags & IEEE80211_NODE_HT)
- + mcs = rate;
- + else
- + mcs = rt2860_rate2mcs(rate);
- +
- + if (type == IEEE80211_FC0_TYPE_DATA)
- + wcid = !IEEE80211_IS_MULTICAST(wh->i_addr1) ? rni->staid : RT2860_WCID_MCAST;
- + else
- + wcid = RT2860_WCID_RESERVED;
- +
- + /* calculate MPDU length without padding */
- +
- + hdrsize = ieee80211_anyhdrsize(wh);
- + hdrspace = ieee80211_anyhdrspace(ic, wh);
- + mpdu_len = m->m_pkthdr.len - hdrspace + hdrsize;
- +
- + memset(txwi, 0, sizeof(struct rt2860_txwi));
- +
- + txwi->wcid = wcid;
- +
- + /* MIMO power save */
- +
- + if ((ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_flags & IEEE80211_NODE_MIMO_PS))
- + {
- + if (mcs > 7)
- + {
- + if (ni->ni_flags & IEEE80211_NODE_MIMO_RTS)
- + {
- + /* dynamic MIMO power save */
- +
- + txwi->mpdu_density_flags |=
- + (RT2860_TXWI_FLAGS_MIMOPS << RT2860_TXWI_FLAGS_SHIFT);
- + }
- + else
- + {
- + /* static MIMO power save */
- +
- + mcs = 7;
- + }
- + }
- +
- + mimops = 1;
- + }
- + else
- + {
- + mimops = 0;
- + }
- +
- + pid = (mcs < 0xf) ? (mcs + 1) : mcs;
- +
- + txwi->pid_mpdu_len = ((htole16(pid) & RT2860_TXWI_PID_MASK) <<
- + RT2860_TXWI_PID_SHIFT) | ((htole16(mpdu_len) & RT2860_TXWI_MPDU_LEN_MASK) <<
- + RT2860_TXWI_MPDU_LEN_SHIFT);
- +
- + stbc = sc->tx_stbc && (mcs <= 7) && (vap->iv_htcaps & IEEE80211_HTCAP_TXSTBC) &&
- + (ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_htcap & IEEE80211_HTCAP_RXSTBC);
- +
- + shortgi = ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) && (ni->ni_flags & IEEE80211_NODE_SGI20) && (ni->ni_chw == 20)) ||
- + ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) && (ni->ni_flags & IEEE80211_NODE_SGI40) && (ni->ni_chw == 40));
- +
- + txwi->phymode_ifs_stbc_shortgi |=
- + ((stbc & RT2860_TXWI_STBC_MASK) << RT2860_TXWI_STBC_SHIFT) |
- + ((shortgi & RT2860_TXWI_SHORTGI_MASK) << RT2860_TXWI_SHORTGI_SHIFT);
- +
- + if (ni->ni_flags & IEEE80211_NODE_HT)
- + {
- + txwi->phymode_ifs_stbc_shortgi |=
- + (RT2860_TXWI_PHYMODE_HT_MIXED << RT2860_TXWI_PHYMODE_SHIFT);
- + }
- + else
- + {
- + if (ieee80211_rate2phytype(ic->ic_rt, rate) != IEEE80211_T_OFDM)
- + {
- + txwi->phymode_ifs_stbc_shortgi |=
- + (RT2860_TXWI_PHYMODE_CCK << RT2860_TXWI_PHYMODE_SHIFT);
- +
- + if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
- + mcs |= RT2860_TXWI_MCS_SHOTPRE;
- + }
- + else
- + {
- + txwi->phymode_ifs_stbc_shortgi |=
- + (RT2860_TXWI_PHYMODE_OFDM << RT2860_TXWI_PHYMODE_SHIFT);
- + }
- + }
- +
- + if ((ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_chw == 40))
- + bw = RT2860_TXWI_BW_40;
- + else
- + bw = RT2860_TXWI_BW_20;
- +
- + txwi->bw_mcs = ((bw & RT2860_TXWI_BW_MASK) << RT2860_TXWI_BW_SHIFT) |
- + ((mcs & RT2860_TXWI_MCS_MASK) << RT2860_TXWI_MCS_SHIFT);
- +
- + txwi->txop = (RT2860_TXWI_TXOP_HT << RT2860_TXWI_TXOP_SHIFT);
- +
- + if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
- + (!hasqos || (qos & IEEE80211_QOS_ACKPOLICY) != IEEE80211_QOS_ACKPOLICY_NOACK))
- + {
- + txwi->bawin_size_xflags |=
- + (RT2860_TXWI_XFLAGS_ACK << RT2860_TXWI_XFLAGS_SHIFT);
- +
- + if (ni->ni_flags & IEEE80211_NODE_HT)
- + {
- + /* preamble + plcp + signal extension + SIFS */
- +
- + dur = 16 + 4 + 6 + 10;
- + }
- + else
- + {
- + dur = ieee80211_ack_duration(ic->ic_rt, rate,
- + ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- + }
- +
- + *(uint16_t *) wh->i_dur = htole16(dur);
- + }
- +
- + /* check for A-MPDU */
- +
- + if (m->m_flags & M_AMPDU_MPDU)
- + {
- + ac = M_WME_GETAC(m);
- + tid = WME_AC_TO_TID(ac);
- + tx_ampdu = &ni->ni_tx_ampdu[ac];
- +
- + mpdu_density = RT2860_MS(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
- + bawin_size = tx_ampdu->txa_wnd;
- +
- + txwi->mpdu_density_flags |=
- + ((mpdu_density & RT2860_TXWI_MPDU_DENSITY_MASK) << RT2860_TXWI_MPDU_DENSITY_SHIFT) |
- + (RT2860_TXWI_FLAGS_AMPDU << RT2860_TXWI_FLAGS_SHIFT);
- +
- + txwi->bawin_size_xflags |=
- + ((bawin_size & RT2860_TXWI_BAWIN_SIZE_MASK) << RT2860_TXWI_BAWIN_SIZE_SHIFT);
- +
- + seqno = ni->ni_txseqs[tid]++;
- +
- + *(uint16_t *) &wh->i_seq[0] = htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
- +
- + ampdu = 1;
- + }
- + else
- + {
- + mpdu_density = 0;
- + bawin_size = 0;
- + ampdu = 0;
- + }
- +
- + /* ask MAC to insert timestamp into probe responses */
- +
- + if ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
- + (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
- + txwi->mpdu_density_flags |=
- + (RT2860_TXWI_FLAGS_TS << RT2860_TXWI_FLAGS_SHIFT);
- +
- + if (ieee80211_radiotap_active_vap(vap))
- + {
- + tap = &sc->txtap;
- +
- + tap->flags = IEEE80211_RADIOTAP_F_DATAPAD;
- + tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
- + tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
- + tap->chan_ieee = ic->ic_curchan->ic_ieee;
- + tap->chan_maxpow = 0;
- +
- + if (ni->ni_flags & IEEE80211_NODE_HT)
- + tap->rate = mcs | IEEE80211_RATE_MCS;
- + else
- + tap->rate = rate;
- +
- + if (mcs & RT2860_TXWI_MCS_SHOTPRE)
- + tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
- +
- + if (shortgi)
- + tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
- +
- + if (wh->i_fc[1] & IEEE80211_FC1_WEP)
- + tap->flags |= IEEE80211_RADIOTAP_F_WEP;
- +
- + /* XXX use temporarily radiotap CFP flag as A-MPDU flag */
- +
- + if (ampdu)
- + tap->flags |= IEEE80211_RADIOTAP_F_CFP;
- +
- + if (wh->i_fc[1] & IEEE80211_FC1_WEP)
- + {
- + wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
- +
- + ieee80211_radiotap_tx(vap, m);
- +
- + wh->i_fc[1] |= IEEE80211_FC1_WEP;
- + }
- + else
- + {
- + ieee80211_radiotap_tx(vap, m);
- + }
- + }
- +
- + /* copy and trim 802.11 header */
- +
- + m_copydata(m, 0, hdrsize, (caddr_t) (txwi + 1));
- + m_adj(m, hdrspace);
- +
- + error = bus_dmamap_load_mbuf_sg(ring->data_dma_tag, data->dma_map, m,
- + dma_seg, &ndmasegs, BUS_DMA_NOWAIT);
- + if (error != 0)
- + {
- + /* too many fragments, linearize */
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_TX,
- + "%s: could not load mbuf DMA map, trying to linearize mbuf: ndmasegs=%d, len=%d, error=%d\n",
- + device_get_nameunit(sc->sc_dev), ndmasegs, m->m_pkthdr.len, error);
- +
- + m = m_defrag(m, M_DONTWAIT);
- + if (m == NULL)
- + return ENOMEM;
- +
- + sc->tx_defrag_packets++;
- +
- + error = bus_dmamap_load_mbuf_sg(ring->data_dma_tag, data->dma_map, m,
- + dma_seg, &ndmasegs, BUS_DMA_NOWAIT);
- + if (error != 0)
- + {
- + printf("%s: could not load mbuf DMA map: ndmasegs=%d, len=%d, error=%d\n",
- + device_get_nameunit(sc->sc_dev), ndmasegs, m->m_pkthdr.len, error);
- + m_freem(m);
- + return error;
- + }
- + }
- +
- + if (m->m_pkthdr.len == 0)
- + ndmasegs = 0;
- +
- + /* determine how many Tx descs are required */
- +
- + ndescs = 1 + ndmasegs / 2;
- + if ((ring->desc_queued + ndescs) > (RT2860_SOFTC_TX_RING_DESC_COUNT - 2))
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_TX,
- + "%s: there are not enough Tx descs\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->no_tx_desc_avail++;
- +
- + bus_dmamap_unload(ring->data_dma_tag, data->dma_map);
- + m_freem(m);
- + return EFBIG;
- + }
- +
- + data->m = m;
- + data->ni = ni;
- +
- + /* set up Tx descs */
- +
- + /* first segment is Tx wireless info and 802.11 header */
- +
- + len = sizeof(struct rt2860_txwi) + hdrsize;
- +
- + /* align end on a 4-bytes boundary */
- +
- + dmalen = (len + 3) & ~ 3;
- +
- + memset((caddr_t) txwi + len, 0, dmalen - len);
- +
- + qsel = RT2860_TXDESC_QSEL_EDCA;
- +
- + desc->sdp0 = htole32(ring->seg0_phys_addr + ring->data_cur * RT2860_TX_DATA_SEG0_SIZE);
- + desc->sdl0 = htole16(dmalen);
- + desc->qsel_flags = (qsel << RT2860_TXDESC_QSEL_SHIFT);
- +
- + /* set up payload segments */
- +
- + for (i = ndmasegs, j = 0; i >= 2; i -= 2)
- + {
- + desc->sdp1 = htole32(dma_seg[j].ds_addr);
- + desc->sdl1 = htole16(dma_seg[j].ds_len);
- +
- + ring->desc_queued++;
- + ring->desc_cur = (ring->desc_cur + 1) % RT2860_SOFTC_TX_RING_DESC_COUNT;
- +
- + j++;
- +
- + desc = &ring->desc[ring->desc_cur];
- +
- + desc->sdp0 = htole32(dma_seg[j].ds_addr);
- + desc->sdl0 = htole16(dma_seg[j].ds_len);
- + desc->qsel_flags = (qsel << RT2860_TXDESC_QSEL_SHIFT);
- +
- + j++;
- + }
- +
- + /* finalize last payload segment */
- +
- + if (i > 0)
- + {
- + desc->sdp1 = htole32(dma_seg[j].ds_addr);
- + desc->sdl1 = htole16(dma_seg[j].ds_len | RT2860_TXDESC_SDL1_LASTSEG);
- + }
- + else
- + {
- + desc->sdl0 |= htole16(RT2860_TXDESC_SDL0_LASTSEG);
- + desc->sdl1 = 0;
- + }
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_TX,
- + "%s: sending data: qid=%d, hdrsize=%d, hdrspace=%d, len=%d, "
- + "bw=%d, stbc=%d, shortgi=%d, mcs=%d, wcid=0x%02x, "
- + "ampdu=%d (density=%d, winsize=%d), mimops=%d, DMA len=%d, ndmasegs=%d, DMA ds_len=%d/%d/%d/%d/%d\n",
- + device_get_nameunit(sc->sc_dev),
- + qid, hdrsize, hdrspace, m->m_pkthdr.len + hdrsize,
- + bw, stbc, shortgi, mcs, wcid, ampdu, mpdu_density, bawin_size, mimops, dmalen, ndmasegs,
- + (int) dma_seg[0].ds_len, (int) dma_seg[1].ds_len, (int) dma_seg[2].ds_len, (int) dma_seg[3].ds_len, (int) dma_seg[4].ds_len);
- +
- + bus_dmamap_sync(ring->seg0_dma_tag, ring->seg0_dma_map,
- + BUS_DMASYNC_PREWRITE);
- + bus_dmamap_sync(ring->data_dma_tag, data->dma_map,
- + BUS_DMASYNC_PREWRITE);
- + bus_dmamap_sync(ring->desc_dma_tag, ring->desc_dma_map,
- + BUS_DMASYNC_PREWRITE);
- +
- + ring->desc_queued++;
- + ring->desc_cur = (ring->desc_cur + 1) % RT2860_SOFTC_TX_RING_DESC_COUNT;
- +
- + ring->data_queued++;
- + ring->data_cur = (ring->data_cur + 1) % RT2860_SOFTC_TX_RING_DATA_COUNT;
- +
- + /* kick Tx */
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_TX_CTX_IDX(qid), ring->desc_cur);
- +
- + return 0;
- + }
- +
- + /*
- + * rt2860_tx_raw
- + static int rt2860_tx_raw(struct rt2860_softc *sc,
- + struct mbuf *m, struct ieee80211_node *ni,
- + const struct ieee80211_bpf_params *params)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_TX,
- + "%s: Tx raw\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + return 0;
- + }
- + */
- +
- + /*
- + * rt2860_intr
- + */
- + void rt2860_intr(void *arg)
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- + uint32_t status;
- +
- + sc = arg;
- + ifp = sc->sc_ifp;
- +
- + /* acknowledge interrupts */
- +
- + status = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_INT_STATUS);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_INT_STATUS, status);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_INTR,
- + "%s: interrupt: status = 0x%08x\n",
- + device_get_nameunit(sc->sc_dev), status);
- +
- + if (status == 0xffffffff || /* device likely went away */
- + status == 0) /* not for us */
- + return;
- +
- + sc->interrupts++;
- +
- + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- + return;
- +
- + if (status & RT2860_REG_INT_TX_COHERENT)
- + rt2860_tx_coherent_intr(sc);
- +
- + if (status & RT2860_REG_INT_RX_COHERENT)
- + rt2860_rx_coherent_intr(sc);
- +
- + if (status & RT2860_REG_INT_TXRX_COHERENT)
- + rt2860_txrx_coherent_intr(sc);
- +
- + if (status & RT2860_REG_INT_FIFO_STA_FULL)
- + rt2860_fifo_sta_full_intr(sc);
- +
- + if (status & RT2860_REG_INT_TX_MGMT_DONE)
- + rt2860_tx_intr(sc, 5);
- +
- + if (status & RT2860_REG_INT_RX_DONE)
- + rt2860_rx_intr(sc);
- +
- + if (status & RT2860_REG_INT_RX_DELAY_DONE)
- + rt2860_rx_delay_intr(sc);
- +
- + if (status & RT2860_REG_INT_TX_HCCA_DONE)
- + rt2860_tx_intr(sc, 4);
- +
- + if (status & RT2860_REG_INT_TX_AC3_DONE)
- + rt2860_tx_intr(sc, 3);
- +
- + if (status & RT2860_REG_INT_TX_AC2_DONE)
- + rt2860_tx_intr(sc, 2);
- +
- + if (status & RT2860_REG_INT_TX_AC1_DONE)
- + rt2860_tx_intr(sc, 1);
- +
- + if (status & RT2860_REG_INT_TX_AC0_DONE)
- + rt2860_tx_intr(sc, 0);
- +
- + if (status & RT2860_REG_INT_TX_DELAY_DONE)
- + rt2860_tx_delay_intr(sc);
- +
- + if (status & RT2860_REG_INT_PRE_TBTT)
- + rt2860_pre_tbtt_intr(sc);
- +
- + if (status & RT2860_REG_INT_TBTT)
- + rt2860_tbtt_intr(sc);
- +
- + if (status & RT2860_REG_INT_MCU_CMD)
- + rt2860_mcu_cmd_intr(sc);
- +
- + if (status & RT2860_REG_INT_AUTO_WAKEUP)
- + rt2860_auto_wakeup_intr(sc);
- +
- + if (status & RT2860_REG_INT_GP_TIMER)
- + rt2860_gp_timer_intr(sc);
- + }
- +
- + /*
- + * rt2860_tx_coherent_intr
- + */
- + static void rt2860_tx_coherent_intr(struct rt2860_softc *sc)
- + {
- + uint32_t tmp;
- + int i;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_INTR,
- + "%s: Tx coherent interrupt\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->tx_coherent_interrupts++;
- +
- + /* restart DMA engine */
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_WPDMA_GLO_CFG);
- +
- + tmp &= ~(RT2860_REG_TX_WB_DDONE |
- + RT2860_REG_RX_DMA_ENABLE |
- + RT2860_REG_TX_DMA_ENABLE);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
- +
- + /* init Tx rings (4 EDCAs + HCCA + MGMT) */
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_COUNT; i++)
- + rt2860_reset_tx_ring(sc, &sc->tx_ring[i]);
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_COUNT; i++)
- + {
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_TX_BASE_PTR(i),
- + sc->tx_ring[i].desc_phys_addr);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_TX_MAX_CNT(i),
- + RT2860_SOFTC_TX_RING_DESC_COUNT);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_TX_CTX_IDX(i), 0);
- + }
- +
- + /* init Rx ring */
- +
- + rt2860_reset_rx_ring(sc, &sc->rx_ring);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_RX_BASE_PTR,
- + sc->rx_ring.desc_phys_addr);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_RX_MAX_CNT,
- + RT2860_SOFTC_RX_RING_DATA_COUNT);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_RX_CALC_IDX,
- + RT2860_SOFTC_RX_RING_DATA_COUNT - 1);
- +
- + rt2860_txrx_enable(sc);
- + }
- +
- + /*
- + * rt2860_rx_coherent_intr
- + */
- + static void rt2860_rx_coherent_intr(struct rt2860_softc *sc)
- + {
- + uint32_t tmp;
- + int i;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_INTR,
- + "%s: Rx coherent interrupt\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->rx_coherent_interrupts++;
- +
- + /* restart DMA engine */
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_WPDMA_GLO_CFG);
- +
- + tmp &= ~(RT2860_REG_TX_WB_DDONE |
- + RT2860_REG_RX_DMA_ENABLE |
- + RT2860_REG_TX_DMA_ENABLE);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
- +
- + /* init Tx rings (4 EDCAs + HCCA + MGMT) */
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_COUNT; i++)
- + rt2860_reset_tx_ring(sc, &sc->tx_ring[i]);
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_COUNT; i++)
- + {
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_TX_BASE_PTR(i),
- + sc->tx_ring[i].desc_phys_addr);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_TX_MAX_CNT(i),
- + RT2860_SOFTC_TX_RING_DESC_COUNT);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_TX_CTX_IDX(i), 0);
- + }
- +
- + /* init Rx ring */
- +
- + rt2860_reset_rx_ring(sc, &sc->rx_ring);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_RX_BASE_PTR,
- + sc->rx_ring.desc_phys_addr);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_RX_MAX_CNT,
- + RT2860_SOFTC_RX_RING_DATA_COUNT);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_RX_CALC_IDX,
- + RT2860_SOFTC_RX_RING_DATA_COUNT - 1);
- +
- + rt2860_txrx_enable(sc);
- + }
- +
- + /*
- + * rt2860_txrx_coherent_intr
- + */
- + static void rt2860_txrx_coherent_intr(struct rt2860_softc *sc)
- + {
- + uint32_t tmp;
- + int i;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_INTR,
- + "%s: Tx/Rx coherent interrupt\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->txrx_coherent_interrupts++;
- +
- + /* restart DMA engine */
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_WPDMA_GLO_CFG);
- +
- + tmp &= ~(RT2860_REG_TX_WB_DDONE |
- + RT2860_REG_RX_DMA_ENABLE |
- + RT2860_REG_TX_DMA_ENABLE);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
- +
- + /* init Tx rings (4 EDCAs + HCCA + MGMT) */
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_COUNT; i++)
- + rt2860_reset_tx_ring(sc, &sc->tx_ring[i]);
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_COUNT; i++)
- + {
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_TX_BASE_PTR(i),
- + sc->tx_ring[i].desc_phys_addr);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_TX_MAX_CNT(i),
- + RT2860_SOFTC_TX_RING_DESC_COUNT);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_TX_CTX_IDX(i), 0);
- + }
- +
- + /* init Rx ring */
- +
- + rt2860_reset_rx_ring(sc, &sc->rx_ring);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_RX_BASE_PTR,
- + sc->rx_ring.desc_phys_addr);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_RX_MAX_CNT,
- + RT2860_SOFTC_RX_RING_DATA_COUNT);
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_RX_CALC_IDX,
- + RT2860_SOFTC_RX_RING_DATA_COUNT - 1);
- +
- + rt2860_txrx_enable(sc);
- + }
- +
- + /*
- + * rt2860_fifo_sta_full_intr
- + */
- + static void rt2860_fifo_sta_full_intr(struct rt2860_softc *sc)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_INTR,
- + "%s: FIFO statistic full interrupt\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->fifo_sta_full_interrupts++;
- +
- + RT2860_SOFTC_LOCK(sc);
- +
- + if (!(sc->intr_disable_mask & RT2860_REG_INT_FIFO_STA_FULL))
- + {
- + rt2860_intr_disable(sc, RT2860_REG_INT_FIFO_STA_FULL);
- +
- + taskqueue_enqueue(sc->taskqueue, &sc->fifo_sta_full_task);
- + }
- +
- + sc->intr_pending_mask |= RT2860_REG_INT_FIFO_STA_FULL;
- +
- + RT2860_SOFTC_UNLOCK(sc);
- + }
- +
- + /*
- + * rt2860_rx_intr
- + */
- + static void rt2860_rx_intr(struct rt2860_softc *sc)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_INTR,
- + "%s: Rx interrupt\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->rx_interrupts++;
- +
- + RT2860_SOFTC_LOCK(sc);
- +
- + if (!(sc->intr_disable_mask & RT2860_REG_INT_RX_DONE))
- + {
- + rt2860_intr_disable(sc, RT2860_REG_INT_RX_DONE);
- +
- + taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
- + }
- +
- + sc->intr_pending_mask |= RT2860_REG_INT_RX_DONE;
- +
- + RT2860_SOFTC_UNLOCK(sc);
- + }
- +
- + /*
- + * rt2860_rx_delay_intr
- + */
- + static void rt2860_rx_delay_intr(struct rt2860_softc *sc)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_INTR,
- + "%s: Rx delay interrupt\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->rx_delay_interrupts++;
- + }
- +
- + /*
- + * rt2860_tx_intr
- + */
- + static void rt2860_tx_intr(struct rt2860_softc *sc, int qid)
- + {
- + KASSERT(qid >= 0 && qid < RT2860_SOFTC_TX_RING_COUNT,
- + ("%s: Tx interrupt: invalid qid=%d\n",
- + device_get_nameunit(sc->sc_dev), qid));
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_INTR,
- + "%s: Tx interrupt: qid=%d\n",
- + device_get_nameunit(sc->sc_dev), qid);
- +
- + sc->tx_interrupts[qid]++;
- +
- + RT2860_SOFTC_LOCK(sc);
- +
- + if (!(sc->intr_disable_mask & (RT2860_REG_INT_TX_AC0_DONE << qid)))
- + {
- + rt2860_intr_disable(sc, (RT2860_REG_INT_TX_AC0_DONE << qid));
- +
- + taskqueue_enqueue(sc->taskqueue, &sc->tx_done_task);
- + }
- +
- + sc->intr_pending_mask |= (RT2860_REG_INT_TX_AC0_DONE << qid);
- +
- + RT2860_SOFTC_UNLOCK(sc);
- + }
- +
- + /*
- + * rt2860_tx_delay_intr
- + */
- + static void rt2860_tx_delay_intr(struct rt2860_softc *sc)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_INTR,
- + "%s: Tx delay interrupt\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->tx_delay_interrupts++;
- + }
- +
- + /*
- + * rt2860_pre_tbtt_intr
- + */
- + static void rt2860_pre_tbtt_intr(struct rt2860_softc *sc)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_INTR,
- + "%s: Pre-TBTT interrupt\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->pre_tbtt_interrupts++;
- + }
- +
- + /*
- + * rt2860_tbtt_intr
- + */
- + static void rt2860_tbtt_intr(struct rt2860_softc *sc)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_INTR,
- + "%s: TBTT interrupt\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->tbtt_interrupts++;
- + }
- +
- + /*
- + * rt2860_mcu_cmd_intr
- + */
- + static void rt2860_mcu_cmd_intr(struct rt2860_softc *sc)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_INTR,
- + "%s: MCU command interrupt\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->mcu_cmd_interrupts++;
- + }
- +
- + /*
- + * rt2860_auto_wakeup_intr
- + */
- + static void rt2860_auto_wakeup_intr(struct rt2860_softc *sc)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_INTR,
- + "%s: auto wakeup interrupt\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->auto_wakeup_interrupts++;
- + }
- +
- + /*
- + * rt2860_gp_timer_intr
- + */
- + static void rt2860_gp_timer_intr(struct rt2860_softc *sc)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_INTR,
- + "%s: GP timer interrupt\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + sc->gp_timer_interrupts++;
- + }
- +
- + /*
- + * rt2860_rx_done_task
- + */
- + static void rt2860_rx_done_task(void *context, int pending)
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- + int again;
- +
- + sc = context;
- + ifp = sc->sc_ifp;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_RX,
- + "%s: Rx done task\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- + return;
- +
- + sc->intr_pending_mask &= ~RT2860_REG_INT_RX_DONE;
- +
- + again = rt2860_rx_eof(sc, sc->rx_process_limit);
- +
- + RT2860_SOFTC_LOCK(sc);
- +
- + if ((sc->intr_pending_mask & RT2860_REG_INT_RX_DONE) || again)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_RX,
- + "%s: Rx done task: scheduling again\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
- + }
- + else
- + {
- + rt2860_intr_enable(sc, RT2860_REG_INT_RX_DONE);
- + }
- +
- + RT2860_SOFTC_UNLOCK(sc);
- + }
- +
- + /*
- + * rt2860_tx_done_task
- + */
- + static void rt2860_tx_done_task(void *context, int pending)
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- + uint32_t intr_mask;
- + int i;
- +
- + sc = context;
- + ifp = sc->sc_ifp;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_TX,
- + "%s: Tx done task\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- + return;
- +
- + for (i = RT2860_SOFTC_TX_RING_COUNT - 1; i >= 0; i--)
- + {
- + if (sc->intr_pending_mask & (RT2860_REG_INT_TX_AC0_DONE << i))
- + {
- + sc->intr_pending_mask &= ~(RT2860_REG_INT_TX_AC0_DONE << i);
- +
- + rt2860_tx_eof(sc, &sc->tx_ring[i]);
- + }
- + }
- +
- + sc->sc_tx_timer = 0;
- +
- + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- +
- + intr_mask = (RT2860_REG_INT_TX_MGMT_DONE |
- + RT2860_REG_INT_TX_HCCA_DONE |
- + RT2860_REG_INT_TX_AC3_DONE |
- + RT2860_REG_INT_TX_AC2_DONE |
- + RT2860_REG_INT_TX_AC1_DONE |
- + RT2860_REG_INT_TX_AC0_DONE);
- +
- + RT2860_SOFTC_LOCK(sc);
- +
- + rt2860_intr_enable(sc, ~sc->intr_pending_mask &
- + (sc->intr_disable_mask & intr_mask));
- +
- + if (sc->intr_pending_mask & intr_mask)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_TX,
- + "%s: Tx done task: scheduling again\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + taskqueue_enqueue(sc->taskqueue, &sc->tx_done_task);
- + }
- +
- + RT2860_SOFTC_UNLOCK(sc);
- +
- + if (!IFQ_IS_EMPTY(&ifp->if_snd))
- + rt2860_start(ifp);
- + }
- +
- + /*
- + * rt2860_fifo_sta_full_task
- + */
- + static void rt2860_fifo_sta_full_task(void *context, int pending)
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- +
- + sc = context;
- + ifp = sc->sc_ifp;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_STATS,
- + "%s: FIFO statistic full task\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- + return;
- +
- + sc->intr_pending_mask &= ~RT2860_REG_INT_FIFO_STA_FULL;
- +
- + rt2860_drain_fifo_stats(sc);
- +
- + RT2860_SOFTC_LOCK(sc);
- +
- + if (sc->intr_pending_mask & RT2860_REG_INT_FIFO_STA_FULL)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_STATS,
- + "%s: FIFO statistic full task: scheduling again\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + taskqueue_enqueue(sc->taskqueue, &sc->fifo_sta_full_task);
- + }
- + else
- + {
- + rt2860_intr_enable(sc, RT2860_REG_INT_FIFO_STA_FULL);
- + }
- +
- + RT2860_SOFTC_UNLOCK(sc);
- +
- + if (!IFQ_IS_EMPTY(&ifp->if_snd))
- + rt2860_start(ifp);
- + }
- +
- + /*
- + * rt2860_periodic_task
- + */
- + static void rt2860_periodic_task(void *context, int pending)
- + {
- + struct rt2860_softc *sc;
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + struct ieee80211vap *vap;
- +
- + sc = context;
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- + vap = TAILQ_FIRST(&ic->ic_vaps);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_PERIODIC,
- + "%s: periodic task: round=%lu\n",
- + device_get_nameunit(sc->sc_dev), sc->periodic_round);
- +
- + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- + return;
- +
- + RT2860_SOFTC_LOCK(sc);
- +
- + sc->periodic_round++;
- +
- + rt2860_update_stats(sc);
- +
- + if ((sc->periodic_round % 10) == 0)
- + {
- + rt2860_bbp_tuning(sc);
- +
- + rt2860_update_raw_counters(sc);
- +
- + rt2860_watchdog(sc);
- +
- + if (vap != NULL && vap->iv_opmode != IEEE80211_M_MONITOR && vap->iv_state == IEEE80211_S_RUN)
- + {
- + if (vap->iv_opmode == IEEE80211_M_STA)
- + rt2860_amrr_update_iter_func(vap, vap->iv_bss);
- + else
- + ieee80211_iterate_nodes(&ic->ic_sta, rt2860_amrr_update_iter_func, vap);
- + }
- + }
- +
- + RT2860_SOFTC_UNLOCK(sc);
- +
- + callout_reset(&sc->periodic_ch, hz / 10, rt2860_periodic, sc);
- + }
- +
- + /*
- + * rt2860_rx_eof
- + */
- + static int rt2860_rx_eof(struct rt2860_softc *sc, int limit)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + struct ieee80211_frame *wh;
- + struct ieee80211_node *ni;
- + struct rt2860_softc_node *rni;
- + struct rt2860_softc_rx_radiotap_header *tap;
- + struct rt2860_softc_rx_ring *ring;
- + struct rt2860_rxdesc *desc;
- + struct rt2860_softc_rx_data *data;
- + struct rt2860_rxwi *rxwi;
- + struct mbuf *m, *mnew;
- + bus_dma_segment_t segs[1];
- + bus_dmamap_t dma_map;
- + uint32_t index, desc_flags;
- + uint8_t cipher_err, rssi, ant, phymode, bw, shortgi, stbc, mcs, keyidx, tid, frag;
- + uint16_t seq;
- + int8_t rssi_dbm;
- + int error, nsegs, len, ampdu, amsdu, rssi_dbm_rel, nframes, i;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- + ring = &sc->rx_ring;
- +
- + nframes = 0;
- +
- + while (limit != 0)
- + {
- + index = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_RX_DRX_IDX);
- + if (ring->cur == index)
- + break;
- +
- + desc = &ring->desc[ring->cur];
- + data = &ring->data[ring->cur];
- +
- + bus_dmamap_sync(ring->desc_dma_tag, ring->desc_dma_map,
- + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- + #ifdef XXX_TESTED_AND_WORKED
- + if (!(desc->sdl0 & htole16(RT2860_RXDESC_SDL0_DDONE)))
- + break;
- + #endif
- +
- + nframes++;
- +
- + mnew = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
- + if (mnew == NULL)
- + {
- + sc->rx_mbuf_alloc_errors++;
- + ifp->if_ierrors++;
- + goto skip;
- + }
- +
- + mnew->m_len = mnew->m_pkthdr.len = MJUMPAGESIZE;
- +
- + error = bus_dmamap_load_mbuf_sg(ring->data_dma_tag, ring->spare_dma_map,
- + mnew, segs, &nsegs, BUS_DMA_NOWAIT);
- + if (error != 0)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_RX,
- + "%s: could not load Rx mbuf DMA map: error=%d, nsegs=%d\n",
- + device_get_nameunit(sc->sc_dev), error, nsegs);
- +
- + m_freem(mnew);
- +
- + sc->rx_mbuf_dmamap_errors++;
- + ifp->if_ierrors++;
- +
- + goto skip;
- + }
- +
- + KASSERT(nsegs == 1, ("%s: too many DMA segments",
- + device_get_nameunit(sc->sc_dev)));
- +
- + bus_dmamap_sync(ring->data_dma_tag, data->dma_map,
- + BUS_DMASYNC_POSTREAD);
- + bus_dmamap_unload(ring->data_dma_tag, data->dma_map);
- +
- + dma_map = data->dma_map;
- + data->dma_map = ring->spare_dma_map;
- + ring->spare_dma_map = dma_map;
- +
- + bus_dmamap_sync(ring->data_dma_tag, data->dma_map,
- + BUS_DMASYNC_PREREAD);
- +
- + m = data->m;
- +
- + data->m = mnew;
- + desc->sdp0 = htole32(segs[0].ds_addr);
- +
- + desc_flags = le32toh(desc->flags);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_RX,
- + "%s: Rx frame: rxdesc flags=0x%08x\n",
- + device_get_nameunit(sc->sc_dev), desc_flags);
- +
- + /* get Rx wireless info */
- +
- + rxwi = mtod(m, struct rt2860_rxwi *);
- + len = (le16toh(rxwi->tid_size) >> RT2860_RXWI_SIZE_SHIFT) &
- + RT2860_RXWI_SIZE_MASK;
- +
- + /* check for L2 padding between IEEE 802.11 frame header and body */
- +
- + if (desc_flags & RT2860_RXDESC_FLAGS_L2PAD)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_RX,
- + "%s: L2 padding: len=%d\n",
- + device_get_nameunit(sc->sc_dev), len);
- +
- + len += 2;
- + }
- +
- + m->m_pkthdr.rcvif = ifp;
- + m->m_data = (caddr_t) (rxwi + 1);
- + m->m_pkthdr.len = m->m_len = len;
- +
- + /* check for crc errors */
- +
- + if (desc_flags & RT2860_RXDESC_FLAGS_CRC_ERR)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_RX,
- + "%s: rxdesc: crc error\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + ifp->if_ierrors++;
- +
- + if (!(ifp->if_flags & IFF_PROMISC))
- + {
- + m_freem(m);
- + goto skip;
- + }
- + }
- +
- + wh = (struct ieee80211_frame *) (rxwi + 1);
- +
- + /* check for cipher errors */
- +
- + if (desc_flags & RT2860_RXDESC_FLAGS_DECRYPTED)
- + {
- + cipher_err = ((desc_flags >> RT2860_RXDESC_FLAGS_CIPHER_ERR_SHIFT) &
- + RT2860_RXDESC_FLAGS_CIPHER_ERR_MASK);
- + if (cipher_err == RT2860_RXDESC_FLAGS_CIPHER_ERR_NONE)
- + {
- + if (wh->i_fc[1] & IEEE80211_FC1_WEP)
- + wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
- +
- + m->m_flags |= M_WEP;
- +
- + sc->rx_cipher_no_errors++;
- + }
- + else
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_RX,
- + "%s: rxdesc: cipher error=0x%02x\n",
- + device_get_nameunit(sc->sc_dev), cipher_err);
- +
- + if (cipher_err == RT2860_RXDESC_FLAGS_CIPHER_ERR_ICV)
- + sc->rx_cipher_icv_errors++;
- + else if (cipher_err == RT2860_RXDESC_FLAGS_CIPHER_ERR_MIC)
- + sc->rx_cipher_mic_errors++;
- + else if (cipher_err == RT2860_RXDESC_FLAGS_CIPHER_ERR_INVALID_KEY)
- + sc->rx_cipher_invalid_key_errors++;
- +
- + if ((cipher_err == RT2860_RXDESC_FLAGS_CIPHER_ERR_MIC) &&
- + (desc_flags & RT2860_RXDESC_FLAGS_MYBSS))
- + {
- + ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) wh);
- + if (ni != NULL)
- + {
- + keyidx = (rxwi->udf_bssidx_keyidx >> RT2860_RXWI_KEYIDX_SHIFT) &
- + RT2860_RXWI_KEYIDX_MASK;
- +
- + ieee80211_notify_michael_failure(ni->ni_vap, wh, keyidx);
- +
- + ieee80211_free_node(ni);
- + }
- + }
- +
- + ifp->if_ierrors++;
- +
- + if (!(ifp->if_flags & IFF_PROMISC))
- + {
- + m_free(m);
- + goto skip;
- + }
- + }
- + }
- + else
- + {
- + if (wh->i_fc[1] & IEEE80211_FC1_WEP)
- + {
- + RT2860_DPRINTF(sc, RT2860_DEBUG_RX,
- + "%s: rxdesc: not decrypted but protected flag set\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + ifp->if_ierrors++;
- +
- + if (!(ifp->if_flags & IFF_PROMISC))
- + {
- + m_free(m);
- + goto skip;
- + }
- + }
- + }
- +
- + /* check for A-MPDU */
- +
- + if (desc_flags & RT2860_RXDESC_FLAGS_BA)
- + {
- + m->m_flags |= M_AMPDU;
- +
- + sc->rx_ampdu++;
- +
- + if (wh->i_fc[1] & IEEE80211_FC1_RETRY)
- + sc->rx_ampdu_retries++;
- +
- + ampdu = 1;
- + }
- + else
- + {
- + ampdu = 0;
- + }
- +
- + /* check for A-MSDU */
- +
- + if (desc_flags & RT2860_RXDESC_FLAGS_AMSDU)
- + {
- + sc->rx_amsdu++;
- +
- + amsdu = 1;
- + }
- + else
- + {
- + amsdu = 0;
- + }
- +
- + ant = rt2860_maxrssi_rxpath(sc, rxwi);
- + rssi = rxwi->rssi[ant];
- + rssi_dbm = rt2860_rssi2dbm(sc, rssi, ant);
- + phymode = ((rxwi->phymode_stbc_shortgi >> RT2860_RXWI_PHYMODE_SHIFT) &
- + RT2860_RXWI_PHYMODE_MASK);
- + bw = ((rxwi->bw_mcs >> RT2860_RXWI_BW_SHIFT) & RT2860_RXWI_BW_MASK);
- + shortgi = ((rxwi->phymode_stbc_shortgi >> RT2860_RXWI_SHORTGI_SHIFT) &
- + RT2860_RXWI_SHORTGI_MASK);
- + stbc = ((rxwi->phymode_stbc_shortgi >> RT2860_RXWI_STBC_SHIFT) &
- + RT2860_RXWI_STBC_MASK);
- + mcs = ((rxwi->bw_mcs >> RT2860_RXWI_MCS_SHIFT) & RT2860_RXWI_MCS_MASK);
- + tid = ((rxwi->tid_size >> RT2860_RXWI_TID_SHIFT) & RT2860_RXWI_TID_MASK);
- + seq = ((rxwi->seq_frag >> RT2860_RXWI_SEQ_SHIFT) & RT2860_RXWI_SEQ_MASK);
- + frag = ((rxwi->seq_frag >> RT2860_RXWI_FRAG_SHIFT) & RT2860_RXWI_FRAG_MASK);
- +
- + if (ieee80211_radiotap_active(ic))
- + {
- + tap = &sc->rxtap;
- +
- + tap->flags = (desc_flags & RT2860_RXDESC_FLAGS_L2PAD) ? IEEE80211_RADIOTAP_F_DATAPAD : 0;
- + tap->dbm_antsignal = rssi_dbm;
- + tap->dbm_antnoise = RT2860_NOISE_FLOOR;
- + tap->antenna = ant;
- + tap->antsignal = rssi;
- + tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
- + tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
- + tap->chan_ieee = ic->ic_curchan->ic_ieee;
- + tap->chan_maxpow = 0;
- +
- + if (phymode == RT2860_TXWI_PHYMODE_HT_MIXED || phymode == RT2860_TXWI_PHYMODE_HT_GF)
- + tap->rate = mcs | IEEE80211_RATE_MCS;
- + else
- + tap->rate = rt2860_rxrate(rxwi);
- +
- + if (desc_flags & RT2860_RXDESC_FLAGS_CRC_ERR)
- + tap->flags |= IEEE80211_RADIOTAP_F_BADFCS;
- +
- + if (desc_flags & RT2860_RXDESC_FLAGS_FRAG)
- + tap->flags |= IEEE80211_RADIOTAP_F_FRAG;
- +
- + if (rxwi->bw_mcs & RT2860_RXWI_MCS_SHOTPRE)
- + tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
- +
- + if ((desc_flags & RT2860_RXDESC_FLAGS_DECRYPTED) ||
- + (wh->i_fc[1] & IEEE80211_FC1_WEP))
- + tap->flags |= IEEE80211_RADIOTAP_F_WEP;
- +
- + if (shortgi)
- + tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
- +
- + /* XXX use temporarily radiotap CFP flag as A-MPDU flag */
- +
- + if (ampdu)
- + tap->flags |= IEEE80211_RADIOTAP_F_CFP;
- + }
- +
- + /*
- + * net80211 assumes that RSSI data are in the range [-127..127] and
- + * in .5 dBm units relative to the current noise floor
- + */
- +
- + rssi_dbm_rel = (rssi_dbm - RT2860_NOISE_FLOOR) * 2;
- + if (rssi_dbm_rel > 127)
- + rssi_dbm_rel = 127;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_RX,
- + "%s: received frame: len=%d, phymode=%d, bw=%d, shortgi=%d, stbc=0x%02x, mcs=%d, "
- + "ant=%d, rssi=%d/%d/%d, snr=%d/%d, wcid=0x%02x, ampdu=%d, amsdu=%d, tid=%d, seq=%d, frag=%d, "
- + "retry=%d, rssi_dbm=%d, rssi_dbm_rel=%d\n",
- + device_get_nameunit(sc->sc_dev),
- + len, phymode, bw, shortgi, stbc, mcs,
- + ant, rxwi->rssi[0], rxwi->rssi[1], rxwi->rssi[2],
- + rxwi->snr[0], rxwi->snr[1],
- + rxwi->wcid, ampdu, amsdu, tid, seq, frag, (wh->i_fc[1] & IEEE80211_FC1_RETRY) ? 1 : 0,
- + rssi_dbm, rssi_dbm_rel);
- +
- + ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *) wh);
- + if (ni != NULL)
- + {
- + rni = (struct rt2860_softc_node *) ni;
- +
- + for (i = 0; i < RT2860_SOFTC_RSSI_COUNT; i++)
- + {
- + rni->last_rssi[i] = rxwi->rssi[i];
- + rni->last_rssi_dbm[i] = rt2860_rssi2dbm(sc, rxwi->rssi[i], i);
- + }
- +
- + ieee80211_input(ni, m, rssi_dbm_rel, RT2860_NOISE_FLOOR);
- + ieee80211_free_node(ni);
- + }
- + else
- + {
- + ieee80211_input_all(ic, m, rssi_dbm_rel, RT2860_NOISE_FLOOR);
- + }
- +
- + skip:
- +
- + desc->sdl0 &= ~htole16(RT2860_RXDESC_SDL0_DDONE);
- +
- + bus_dmamap_sync(ring->desc_dma_tag, ring->desc_dma_map,
- + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- +
- + ring->cur = (ring->cur + 1) % RT2860_SOFTC_RX_RING_DATA_COUNT;
- +
- + limit--;
- + }
- +
- + if (ring->cur == 0)
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_RX_CALC_IDX,
- + RT2860_SOFTC_RX_RING_DATA_COUNT - 1);
- + else
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_RX_CALC_IDX,
- + ring->cur - 1);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_RX,
- + "%s: Rx eof: nframes=%d\n",
- + device_get_nameunit(sc->sc_dev), nframes);
- +
- + sc->rx_packets += nframes;
- +
- + return (limit == 0);
- + }
- +
- + /*
- + * rt2860_tx_eof
- + */
- + static void rt2860_tx_eof(struct rt2860_softc *sc,
- + struct rt2860_softc_tx_ring *ring)
- + {
- + struct ifnet *ifp;
- + struct rt2860_txdesc *desc;
- + struct rt2860_softc_tx_data *data;
- + uint32_t index;
- + int ndescs, nframes;
- +
- + ifp = sc->sc_ifp;
- +
- + ndescs = 0;
- + nframes = 0;
- +
- + for (;;)
- + {
- + index = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_TX_DTX_IDX(ring->qid));
- + if (ring->desc_next == index)
- + break;
- +
- + ndescs++;
- +
- + rt2860_drain_fifo_stats(sc);
- +
- + desc = &ring->desc[ring->desc_next];
- +
- + bus_dmamap_sync(ring->desc_dma_tag, ring->desc_dma_map,
- + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- +
- + if (desc->sdl0 & htole16(RT2860_TXDESC_SDL0_LASTSEG) ||
- + desc->sdl1 & htole16(RT2860_TXDESC_SDL1_LASTSEG))
- + {
- + nframes++;
- +
- + data = &ring->data[ring->data_next];
- +
- + if (data->m->m_flags & M_TXCB)
- + ieee80211_process_callback(data->ni, data->m, 0);
- +
- + bus_dmamap_sync(ring->data_dma_tag, data->dma_map,
- + BUS_DMASYNC_POSTWRITE);
- + bus_dmamap_unload(ring->data_dma_tag, data->dma_map);
- +
- + m_freem(data->m);
- +
- + ieee80211_free_node(data->ni);
- +
- + data->m = NULL;
- + data->ni = NULL;
- +
- + ifp->if_opackets++;
- +
- + RT2860_SOFTC_TX_RING_LOCK(ring);
- +
- + ring->data_queued--;
- + ring->data_next = (ring->data_next + 1) % RT2860_SOFTC_TX_RING_DATA_COUNT;
- +
- + RT2860_SOFTC_TX_RING_UNLOCK(ring);
- + }
- +
- + desc->sdl0 &= ~htole16(RT2860_TXDESC_SDL0_DDONE);
- +
- + bus_dmamap_sync(ring->desc_dma_tag, ring->desc_dma_map,
- + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- +
- + RT2860_SOFTC_TX_RING_LOCK(ring);
- +
- + ring->desc_queued--;
- + ring->desc_next = (ring->desc_next + 1) % RT2860_SOFTC_TX_RING_DESC_COUNT;
- +
- + RT2860_SOFTC_TX_RING_UNLOCK(ring);
- + }
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_TX,
- + "%s: Tx eof: qid=%d, ndescs=%d, nframes=%d\n",
- + device_get_nameunit(sc->sc_dev), ring->qid, ndescs, nframes);
- + }
- +
- + /*
- + * rt2860_update_stats
- + */
- + static void rt2860_update_stats(struct rt2860_softc *sc)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + uint32_t stacnt[3];
- + int beacons, noretryok, retryok, failed, underflows, zerolen;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_STATS,
- + "%s: update statistic\n",
- + device_get_nameunit(sc->sc_dev));
- +
- + rt2860_drain_fifo_stats(sc);
- +
- + /* read and clear Tx statistic registers */
- +
- + rt2860_io_mac_read_multi(sc, RT2860_REG_TX_STA_CNT0,
- + stacnt, sizeof(stacnt));
- +
- + stacnt[0] = le32toh(stacnt[0]);
- + stacnt[1] = le32toh(stacnt[1]);
- + stacnt[2] = le32toh(stacnt[2]);
- +
- + beacons = stacnt[0] >> 16;
- + noretryok = stacnt[1] & 0xffff;
- + retryok = stacnt[1] >> 16;
- + failed = stacnt[0] & 0xffff;
- + underflows = stacnt[2] >> 16;
- + zerolen = stacnt[2] & 0xffff;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_STATS,
- + "%s: update statistic: beacons=%d, noretryok=%d, retryok=%d, failed=%d, underflows=%d, zerolen=%d\n",
- + device_get_nameunit(sc->sc_dev),
- + beacons, noretryok, retryok, failed, underflows, zerolen);
- +
- + ifp->if_oerrors += failed;
- +
- + sc->tx_beacons += beacons;
- + sc->tx_noretryok += noretryok;
- + sc->tx_retryok += retryok;
- + sc->tx_failed += failed;
- + sc->tx_underflows += underflows;
- + sc->tx_zerolen += zerolen;
- + }
- +
- + /*
- + * rt2860_bbp_tuning
- + */
- + static void rt2860_bbp_tuning(struct rt2860_softc *sc)
- + {
- + struct ifnet *ifp;
- + struct ieee80211com *ic;
- + struct ieee80211vap *vap;
- + struct ieee80211_node *ni;
- + int chan, group;
- + int8_t rssi, old, new;
- +
- + /* RT2860C does not support BBP tuning */
- +
- + if (sc->mac_rev == 0x28600100)
- + return;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- + vap = TAILQ_FIRST(&ic->ic_vaps);
- +
- + if ((ic->ic_flags & IEEE80211_F_SCAN) || vap == NULL ||
- + vap->iv_opmode != IEEE80211_M_STA || vap->iv_state != IEEE80211_S_RUN)
- + return;
- +
- + ni = vap->iv_bss;
- +
- + chan = ieee80211_chan2ieee(ic, ni->ni_chan);
- +
- + if (chan <= 14)
- + group = 0;
- + else if (chan <= 64)
- + group = 1;
- + else if (chan <= 128)
- + group = 2;
- + else
- + group = 3;
- +
- + rssi = ieee80211_getrssi(vap);
- +
- + if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
- + {
- + new = 0x2e + sc->lna_gain[group];
- + }
- + else
- + {
- + if (!IEEE80211_IS_CHAN_HT40(ni->ni_chan))
- + new = 0x32 + sc->lna_gain[group] * 5 / 3;
- + else
- + new = 0x3a + sc->lna_gain[group] * 5 / 3;
- + }
- +
- + /* Tune if absolute average RSSI is greater than -80 */
- +
- + if (rssi > 30)
- + new += 0x10;
- +
- + old = rt2860_io_bbp_read(sc, 66);
- +
- + if (old != new)
- + rt2860_io_bbp_write(sc, 66, new);
- + }
- +
- + /*
- + * rt2860_watchdog
- + */
- + static void rt2860_watchdog(struct rt2860_softc *sc)
- + {
- + uint32_t tmp;
- + int ntries;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_PBF_TXRXQ_PCNT);
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_WATCHDOG,
- + "%s: watchdog: TXRXQ_PCNT=0x%08x\n",
- + device_get_nameunit(sc->sc_dev), tmp);
- +
- + if (((tmp >> RT2860_REG_TX0Q_PCNT_SHIFT) & RT2860_REG_TX0Q_PCNT_MASK) != 0)
- + {
- + sc->tx_queue_not_empty[0]++;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_PBF_CFG, 0xf40012);
- +
- + for (ntries = 0; ntries < 10; ntries++)
- + {
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_PBF_TXRXQ_PCNT);
- + if (((tmp >> RT2860_REG_TX0Q_PCNT_SHIFT) & RT2860_REG_TX0Q_PCNT_MASK) == 0)
- + break;
- +
- + DELAY(1);
- + }
- +
- + rt2860_io_mac_write(sc, RT2860_REG_PBF_CFG, 0xf40006);
- + }
- +
- + if (((tmp >> RT2860_REG_TX1Q_PCNT_SHIFT) & RT2860_REG_TX1Q_PCNT_MASK) != 0)
- + {
- + sc->tx_queue_not_empty[1]++;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_PBF_CFG, 0xf4000a);
- +
- + for (ntries = 0; ntries < 10; ntries++)
- + {
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_PBF_TXRXQ_PCNT);
- + if (((tmp >> RT2860_REG_TX1Q_PCNT_SHIFT) & RT2860_REG_TX1Q_PCNT_MASK) == 0)
- + break;
- +
- + DELAY(1);
- + }
- +
- + rt2860_io_mac_write(sc, RT2860_REG_PBF_CFG, 0xf40006);
- + }
- + }
- +
- + /*
- + * rt2860_drain_fifo_stats
- + */
- + static void rt2860_drain_fifo_stats(struct rt2860_softc *sc)
- + {
- + struct ifnet *ifp;
- + uint32_t stats;
- + uint8_t wcid, mcs, pid;
- + int ok, agg, retrycnt;
- +
- + ifp = sc->sc_ifp;
- +
- + /* drain Tx status FIFO (maxsize = 16) */
- +
- + while ((stats = rt2860_io_mac_read(sc, RT2860_REG_TX_STA_FIFO)) &
- + RT2860_REG_TX_STA_FIFO_VALID)
- + {
- + wcid = (stats >> RT2860_REG_TX_STA_FIFO_WCID_SHIFT) &
- + RT2860_REG_TX_STA_FIFO_WCID_MASK;
- +
- + /* if no ACK was requested, no feedback is available */
- +
- + if (!(stats & RT2860_REG_TX_STA_FIFO_ACK_REQ) || wcid == RT2860_WCID_RESERVED)
- + continue;
- +
- + /* update AMRR statistic */
- +
- + ok = (stats & RT2860_REG_TX_STA_FIFO_TX_OK) ? 1 : 0;
- + agg = (stats & RT2860_REG_TX_STA_FIFO_AGG) ? 1 : 0;
- + mcs = (stats >> RT2860_REG_TX_STA_FIFO_MCS_SHIFT) &
- + RT2860_REG_TX_STA_FIFO_MCS_MASK;
- + pid = (stats >> RT2860_REG_TX_STA_FIFO_PID_SHIFT) &
- + RT2860_REG_TX_STA_FIFO_PID_MASK;
- + retrycnt = (mcs < 0xf) ? (pid - mcs - 1) : 0;
- +
- + RT2860_DPRINTF(sc, RT2860_DEBUG_STATS,
- + "%s: FIFO statistic: wcid=0x%02x, ok=%d, agg=%d, mcs=0x%02x, pid=0x%02x, retrycnt=%d\n",
- + device_get_nameunit(sc->sc_dev),
- + wcid, ok, agg, mcs, pid, retrycnt);
- +
- + rt2860_amrr_tx_complete(&sc->amrr_node[wcid], ok, retrycnt);
- +
- + if (!ok)
- + ifp->if_oerrors++;
- + }
- + }
- +
- + /*
- + * rt2860_update_raw_counters
- + */
- + static void rt2860_update_raw_counters(struct rt2860_softc *sc)
- + {
- + uint32_t tmp;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_TX_AGG_CNT);
- +
- + sc->tx_nonagg += tmp & 0xffff;
- + sc->tx_agg += tmp >> 16;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_TX_AGG_CNT0);
- +
- + sc->tx_ampdu += (tmp & 0xffff) / 1 + (tmp >> 16) / 2;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_TX_AGG_CNT1);
- +
- + sc->tx_ampdu += (tmp & 0xffff) / 3 + (tmp >> 16) / 4;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_TX_AGG_CNT2);
- +
- + sc->tx_ampdu += (tmp & 0xffff) / 5 + (tmp >> 16) / 6;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_TX_AGG_CNT3);
- +
- + sc->tx_ampdu += (tmp & 0xffff) / 7 + (tmp >> 16) / 8;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_TX_AGG_CNT4);
- +
- + sc->tx_ampdu += (tmp & 0xffff) / 9 + (tmp >> 16) / 10;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_TX_AGG_CNT5);
- +
- + sc->tx_ampdu += (tmp & 0xffff) / 11 + (tmp >> 16) / 12;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_TX_AGG_CNT6);
- +
- + sc->tx_ampdu += (tmp & 0xffff) / 13 + (tmp >> 16) / 14;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_TX_AGG_CNT7);
- +
- + sc->tx_ampdu += (tmp & 0xffff) / 15 + (tmp >> 16) / 16;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_RX_STA_CNT0);
- +
- + sc->rx_crc_errors += tmp & 0xffff;
- + sc->rx_phy_errors += tmp >> 16;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_RX_STA_CNT1);
- +
- + sc->rx_false_ccas += tmp & 0xffff;
- + sc->rx_plcp_errors += tmp >> 16;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_RX_STA_CNT2);
- +
- + sc->rx_dup_packets += tmp & 0xffff;
- + sc->rx_fifo_overflows += tmp >> 16;
- +
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_TXRX_MPDU_DEN_CNT);
- +
- + sc->tx_mpdu_zero_density += tmp & 0xffff;
- + sc->rx_mpdu_zero_density += tmp >> 16;
- + }
- +
- + /*
- + * rt2860_intr_enable
- + */
- + static void rt2860_intr_enable(struct rt2860_softc *sc, uint32_t intr_mask)
- + {
- + uint32_t tmp;
- +
- + sc->intr_disable_mask &= ~intr_mask;
- +
- + tmp = sc->intr_enable_mask & ~sc->intr_disable_mask;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_INT_MASK, tmp);
- + }
- +
- + /*
- + * rt2860_intr_disable
- + */
- + static void rt2860_intr_disable(struct rt2860_softc *sc, uint32_t intr_mask)
- + {
- + uint32_t tmp;
- +
- + sc->intr_disable_mask |= intr_mask;
- +
- + tmp = sc->intr_enable_mask & ~sc->intr_disable_mask;
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_INT_MASK, tmp);
- + }
- +
- + /*
- + * rt2860_txrx_enable
- + */
- + static int rt2860_txrx_enable(struct rt2860_softc *sc)
- + {
- + struct ieee80211com *ic;
- + struct ifnet *ifp;
- + uint32_t tmp;
- + int ntries;
- +
- + ifp = sc->sc_ifp;
- + ic = ifp->if_l2com;
- +
- + /* enable Tx/Rx DMA engine */
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SYS_CTRL, RT2860_REG_TX_ENABLE);
- +
- + for (ntries = 0; ntries < 200; ntries++)
- + {
- + tmp = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_WPDMA_GLO_CFG);
- + if (!(tmp & (RT2860_REG_TX_DMA_BUSY | RT2860_REG_RX_DMA_BUSY)))
- + break;
- +
- + DELAY(1000);
- + }
- +
- + if (ntries == 200)
- + {
- + printf("%s: timeout waiting for DMA engine\n",
- + device_get_nameunit(sc->sc_dev));
- + return -1;
- + }
- +
- + DELAY(50);
- +
- + tmp |= RT2860_REG_TX_WB_DDONE |
- + RT2860_REG_RX_DMA_ENABLE |
- + RT2860_REG_TX_DMA_ENABLE |
- + (RT2860_REG_WPDMA_BT_SIZE64 << RT2860_REG_WPDMA_BT_SIZE_SHIFT);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
- +
- + /* set Rx filter */
- +
- + tmp = RT2860_REG_RX_FILTER_DROP_CRC_ERR |
- + RT2860_REG_RX_FILTER_DROP_PHY_ERR;
- +
- + if (ic->ic_opmode != IEEE80211_M_MONITOR)
- + {
- + tmp |= RT2860_REG_RX_FILTER_DROP_DUPL |
- + RT2860_REG_RX_FILTER_DROP_CTS |
- + RT2860_REG_RX_FILTER_DROP_BA |
- + RT2860_REG_RX_FILTER_DROP_ACK |
- + RT2860_REG_RX_FILTER_DROP_VER_ERR |
- + RT2860_REG_RX_FILTER_DROP_CTRL_RSV |
- + RT2860_REG_RX_FILTER_DROP_CFACK |
- + RT2860_REG_RX_FILTER_DROP_CFEND;
- +
- + if (ic->ic_opmode == IEEE80211_M_STA)
- + tmp |= RT2860_REG_RX_FILTER_DROP_RTS |
- + RT2860_REG_RX_FILTER_DROP_PSPOLL;
- +
- + if (!(ifp->if_flags & IFF_PROMISC))
- + tmp |= RT2860_REG_RX_FILTER_DROP_UC_NOME;
- + }
- +
- + rt2860_io_mac_write(sc, RT2860_REG_RX_FILTER_CFG, tmp);
- +
- + rt2860_io_mac_write(sc, RT2860_REG_SYS_CTRL,
- + RT2860_REG_RX_ENABLE | RT2860_REG_TX_ENABLE);
- +
- + return 0;
- + }
- +
- + /*
- + * rt2860_alloc_rx_ring
- + */
- + static int rt2860_alloc_rx_ring(struct rt2860_softc *sc,
- + struct rt2860_softc_rx_ring *ring)
- + {
- + struct rt2860_rxdesc *desc;
- + struct rt2860_softc_rx_data *data;
- + bus_dma_segment_t segs[1];
- + int i, nsegs, error;
- +
- + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), PAGE_SIZE, 0,
- + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- + RT2860_SOFTC_RX_RING_DATA_COUNT * sizeof(struct rt2860_rxdesc), 1,
- + RT2860_SOFTC_RX_RING_DATA_COUNT * sizeof(struct rt2860_rxdesc),
- + 0, NULL, NULL, &ring->desc_dma_tag);
- + if (error != 0)
- + {
- + printf("%s: could not create Rx desc DMA tag\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + error = bus_dmamem_alloc(ring->desc_dma_tag, (void **) &ring->desc,
- + BUS_DMA_NOWAIT | BUS_DMA_ZERO, &ring->desc_dma_map);
- + if (error != 0)
- + {
- + printf("%s: could not allocate Rx desc DMA memory\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + error = bus_dmamap_load(ring->desc_dma_tag, ring->desc_dma_map,
- + ring->desc,
- + RT2860_SOFTC_RX_RING_DATA_COUNT * sizeof(struct rt2860_rxdesc),
- + rt2860_dma_map_addr, &ring->desc_phys_addr, 0);
- + if (error != 0)
- + {
- + printf("%s: could not load Rx desc DMA map\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), PAGE_SIZE, 0,
- + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- + MJUMPAGESIZE, 1, MJUMPAGESIZE, 0, NULL, NULL,
- + &ring->data_dma_tag);
- + if (error != 0)
- + {
- + printf("%s: could not create Rx data DMA tag\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + for (i = 0; i < RT2860_SOFTC_RX_RING_DATA_COUNT; i++)
- + {
- + desc = &ring->desc[i];
- + data = &ring->data[i];
- +
- + error = bus_dmamap_create(ring->data_dma_tag, 0, &data->dma_map);
- + if (error != 0)
- + {
- + printf("%s: could not create Rx data DMA map\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + data->m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
- + if (data->m == NULL)
- + {
- + printf("%s: could not allocate Rx mbuf\n",
- + device_get_nameunit(sc->sc_dev));
- + error = ENOMEM;
- + goto fail;
- + }
- +
- + data->m->m_len = data->m->m_pkthdr.len = MJUMPAGESIZE;
- +
- + error = bus_dmamap_load_mbuf_sg(ring->data_dma_tag, data->dma_map,
- + data->m, segs, &nsegs, BUS_DMA_NOWAIT);
- + if (error != 0)
- + {
- + printf("%s: could not load Rx mbuf DMA map\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + KASSERT(nsegs == 1, ("%s: too many DMA segments",
- + device_get_nameunit(sc->sc_dev)));
- +
- + desc->sdp0 = htole32(segs[0].ds_addr);
- + desc->sdl0 = htole16(MJUMPAGESIZE);
- + }
- +
- + error = bus_dmamap_create(ring->data_dma_tag, 0, &ring->spare_dma_map);
- + if (error != 0)
- + {
- + printf("%s: could not create Rx spare DMA map\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + bus_dmamap_sync(ring->desc_dma_tag, ring->desc_dma_map,
- + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- +
- + return 0;
- +
- + fail:
- +
- + rt2860_free_rx_ring(sc, ring);
- +
- + return error;
- + }
- +
- + /*
- + * rt2860_reset_rx_ring
- + */
- + static void rt2860_reset_rx_ring(struct rt2860_softc *sc,
- + struct rt2860_softc_rx_ring *ring)
- + {
- + struct rt2860_rxdesc *desc;
- + int i;
- +
- + for (i = 0; i < RT2860_SOFTC_RX_RING_DATA_COUNT; i++)
- + {
- + desc = &ring->desc[i];
- +
- + desc->sdl0 &= ~htole16(RT2860_RXDESC_SDL0_DDONE);
- + }
- +
- + bus_dmamap_sync(ring->desc_dma_tag, ring->desc_dma_map,
- + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- +
- + ring->cur = 0;
- + }
- +
- + /*
- + * rt2860_free_rx_ring
- + */
- + static void rt2860_free_rx_ring(struct rt2860_softc *sc,
- + struct rt2860_softc_rx_ring *ring)
- + {
- + struct rt2860_softc_rx_data *data;
- + int i;
- +
- + if (ring->desc != NULL)
- + {
- + bus_dmamap_sync(ring->desc_dma_tag, ring->desc_dma_map,
- + BUS_DMASYNC_POSTWRITE);
- + bus_dmamap_unload(ring->desc_dma_tag, ring->desc_dma_map);
- + bus_dmamem_free(ring->desc_dma_tag, ring->desc,
- + ring->desc_dma_map);
- + }
- +
- + if (ring->desc_dma_tag != NULL)
- + bus_dma_tag_destroy(ring->desc_dma_tag);
- +
- + for (i = 0; i < RT2860_SOFTC_RX_RING_DATA_COUNT; i++)
- + {
- + data = &ring->data[i];
- +
- + if (data->m != NULL)
- + {
- + bus_dmamap_sync(ring->data_dma_tag, data->dma_map,
- + BUS_DMASYNC_POSTREAD);
- + bus_dmamap_unload(ring->data_dma_tag, data->dma_map);
- + m_freem(data->m);
- + }
- +
- + if (data->dma_map != NULL)
- + bus_dmamap_destroy(ring->data_dma_tag, data->dma_map);
- + }
- +
- + if (ring->spare_dma_map != NULL)
- + bus_dmamap_destroy(ring->data_dma_tag, ring->spare_dma_map);
- +
- + if (ring->data_dma_tag != NULL)
- + bus_dma_tag_destroy(ring->data_dma_tag);
- + }
- +
- + /*
- + * rt2860_alloc_tx_ring
- + */
- + static int rt2860_alloc_tx_ring(struct rt2860_softc *sc,
- + struct rt2860_softc_tx_ring *ring, int qid)
- + {
- + struct rt2860_softc_tx_data *data;
- + int error, i;
- +
- + mtx_init(&ring->lock, device_get_nameunit(sc->sc_dev), NULL, MTX_DEF);
- +
- + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), PAGE_SIZE, 0,
- + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- + RT2860_SOFTC_TX_RING_DESC_COUNT * sizeof(struct rt2860_txdesc), 1,
- + RT2860_SOFTC_TX_RING_DESC_COUNT * sizeof(struct rt2860_txdesc),
- + 0, NULL, NULL, &ring->desc_dma_tag);
- + if (error != 0)
- + {
- + printf("%s: could not create Tx desc DMA tag\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + error = bus_dmamem_alloc(ring->desc_dma_tag, (void **) &ring->desc,
- + BUS_DMA_NOWAIT | BUS_DMA_ZERO, &ring->desc_dma_map);
- + if (error != 0)
- + {
- + printf("%s: could not allocate Tx desc DMA memory\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + error = bus_dmamap_load(ring->desc_dma_tag, ring->desc_dma_map,
- + ring->desc,
- + RT2860_SOFTC_TX_RING_DESC_COUNT * sizeof(struct rt2860_txdesc),
- + rt2860_dma_map_addr, &ring->desc_phys_addr, 0);
- + if (error != 0)
- + {
- + printf("%s: could not load Tx desc DMA map\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + ring->desc_queued = 0;
- + ring->desc_cur = 0;
- + ring->desc_next = 0;
- +
- + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), PAGE_SIZE, 0,
- + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- + RT2860_SOFTC_TX_RING_DATA_COUNT * RT2860_TX_DATA_SEG0_SIZE, 1,
- + RT2860_SOFTC_TX_RING_DATA_COUNT * RT2860_TX_DATA_SEG0_SIZE,
- + 0, NULL, NULL, &ring->seg0_dma_tag);
- + if (error != 0)
- + {
- + printf("%s: could not create Tx seg0 DMA tag\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + error = bus_dmamem_alloc(ring->seg0_dma_tag, (void **) &ring->seg0,
- + BUS_DMA_NOWAIT | BUS_DMA_ZERO, &ring->seg0_dma_map);
- + if (error != 0)
- + {
- + printf("%s: could not allocate Tx seg0 DMA memory\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + error = bus_dmamap_load(ring->seg0_dma_tag, ring->seg0_dma_map,
- + ring->seg0,
- + RT2860_SOFTC_TX_RING_DATA_COUNT * RT2860_TX_DATA_SEG0_SIZE,
- + rt2860_dma_map_addr, &ring->seg0_phys_addr, 0);
- + if (error != 0)
- + {
- + printf("%s: could not load Tx seg0 DMA map\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), PAGE_SIZE, 0,
- + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- + MJUMPAGESIZE, RT2860_SOFTC_MAX_SCATTER, MJUMPAGESIZE, 0, NULL, NULL,
- + &ring->data_dma_tag);
- + if (error != 0)
- + {
- + printf("%s: could not create Tx data DMA tag\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_DATA_COUNT; i++)
- + {
- + data = &ring->data[i];
- +
- + error = bus_dmamap_create(ring->data_dma_tag, 0, &data->dma_map);
- + if (error != 0)
- + {
- + printf("%s: could not create Tx data DMA map\n",
- + device_get_nameunit(sc->sc_dev));
- + goto fail;
- + }
- + }
- +
- + ring->data_queued = 0;
- + ring->data_cur = 0;
- + ring->data_next = 0;
- +
- + ring->qid = qid;
- +
- + return 0;
- +
- + fail:
- +
- + rt2860_free_tx_ring(sc, ring);
- +
- + return error;
- + }
- +
- + /*
- + * rt2860_reset_tx_ring
- + */
- + static void rt2860_reset_tx_ring(struct rt2860_softc *sc,
- + struct rt2860_softc_tx_ring *ring)
- + {
- + struct rt2860_softc_tx_data *data;
- + struct rt2860_txdesc *desc;
- + int i;
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_DESC_COUNT; i++)
- + {
- + desc = &ring->desc[i];
- +
- + desc->sdl0 = 0;
- + desc->sdl1 = 0;
- + }
- +
- + ring->desc_queued = 0;
- + ring->desc_cur = 0;
- + ring->desc_next = 0;
- +
- + bus_dmamap_sync(ring->desc_dma_tag, ring->desc_dma_map,
- + BUS_DMASYNC_PREWRITE);
- +
- + bus_dmamap_sync(ring->seg0_dma_tag, ring->seg0_dma_map,
- + BUS_DMASYNC_PREWRITE);
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_DATA_COUNT; i++)
- + {
- + data = &ring->data[i];
- +
- + if (data->m != NULL)
- + {
- + bus_dmamap_sync(ring->data_dma_tag, data->dma_map,
- + BUS_DMASYNC_POSTWRITE);
- + bus_dmamap_unload(ring->data_dma_tag, data->dma_map);
- + m_freem(data->m);
- + data->m = NULL;
- + }
- +
- + if (data->ni != NULL)
- + {
- + ieee80211_free_node(data->ni);
- + data->ni = NULL;
- + }
- + }
- +
- + ring->data_queued = 0;
- + ring->data_cur = 0;
- + ring->data_next = 0;
- + }
- +
- + /*
- + * rt2860_free_tx_ring
- + */
- + static void rt2860_free_tx_ring(struct rt2860_softc *sc,
- + struct rt2860_softc_tx_ring *ring)
- + {
- + struct rt2860_softc_tx_data *data;
- + int i;
- +
- + if (ring->desc != NULL)
- + {
- + bus_dmamap_sync(ring->desc_dma_tag, ring->desc_dma_map,
- + BUS_DMASYNC_POSTWRITE);
- + bus_dmamap_unload(ring->desc_dma_tag, ring->desc_dma_map);
- + bus_dmamem_free(ring->desc_dma_tag, ring->desc,
- + ring->desc_dma_map);
- + }
- +
- + if (ring->desc_dma_tag != NULL)
- + bus_dma_tag_destroy(ring->desc_dma_tag);
- +
- + if (ring->seg0 != NULL)
- + {
- + bus_dmamap_sync(ring->seg0_dma_tag, ring->seg0_dma_map,
- + BUS_DMASYNC_POSTWRITE);
- + bus_dmamap_unload(ring->seg0_dma_tag, ring->seg0_dma_map);
- + bus_dmamem_free(ring->seg0_dma_tag, ring->seg0,
- + ring->seg0_dma_map);
- + }
- +
- + if (ring->seg0_dma_tag != NULL)
- + bus_dma_tag_destroy(ring->seg0_dma_tag);
- +
- + for (i = 0; i < RT2860_SOFTC_TX_RING_DATA_COUNT; i++)
- + {
- + data = &ring->data[i];
- +
- + if (data->m != NULL)
- + {
- + bus_dmamap_sync(ring->data_dma_tag, data->dma_map,
- + BUS_DMASYNC_POSTWRITE);
- + bus_dmamap_unload(ring->data_dma_tag, data->dma_map);
- + m_freem(data->m);
- + }
- +
- + if (data->ni != NULL)
- + ieee80211_free_node(data->ni);
- +
- + if (data->dma_map != NULL)
- + bus_dmamap_destroy(ring->data_dma_tag, data->dma_map);
- + }
- +
- + if (ring->data_dma_tag != NULL)
- + bus_dma_tag_destroy(ring->data_dma_tag);
- +
- + mtx_destroy(&ring->lock);
- + }
- +
- + /*
- + * rt2860_dma_map_addr
- + */
- + static void rt2860_dma_map_addr(void *arg, bus_dma_segment_t *segs,
- + int nseg, int error)
- + {
- + if (error != 0)
- + return;
- +
- + KASSERT(nseg == 1, ("too many DMA segments, %d should be 1", nseg));
- +
- + *(bus_addr_t *) arg = segs[0].ds_addr;
- + }
- +
- + /*
- + * rt2860_sysctl_attach
- + */
- + static void rt2860_sysctl_attach(struct rt2860_softc *sc)
- + {
- + struct sysctl_ctx_list *ctx;
- + struct sysctl_oid *tree;
- + struct sysctl_oid *stats;
- +
- + ctx = device_get_sysctl_ctx(sc->sc_dev);
- + tree = device_get_sysctl_tree(sc->sc_dev);
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
- + "tx_stbc", CTLFLAG_RW, &sc->tx_stbc, 0,
- + "Tx STBC");
- +
- + /* statistic counters */
- +
- + stats = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
- + "stats", CTLFLAG_RD, 0, "statistic");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "interrupts", CTLFLAG_RD, &sc->interrupts, 0,
- + "all interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_coherent_interrupts", CTLFLAG_RD, &sc->tx_coherent_interrupts, 0,
- + "Tx coherent interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_coherent_interrupts", CTLFLAG_RD, &sc->rx_coherent_interrupts, 0,
- + "Rx coherent interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "txrx_coherent_interrupts", CTLFLAG_RD, &sc->txrx_coherent_interrupts, 0,
- + "Tx/Rx coherent interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "fifo_sta_full_interrupts", CTLFLAG_RD, &sc->fifo_sta_full_interrupts, 0,
- + "FIFO statistic full interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_interrupts", CTLFLAG_RD, &sc->rx_interrupts, 0,
- + "Rx interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_delay_interrupts", CTLFLAG_RD, &sc->rx_delay_interrupts, 0,
- + "Rx delay interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_mgmt_interrupts", CTLFLAG_RD, &sc->tx_interrupts[5], 0,
- + "Tx MGMT interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_hcca_interrupts", CTLFLAG_RD, &sc->tx_interrupts[4], 0,
- + "Tx HCCA interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac3_interrupts", CTLFLAG_RD, &sc->tx_interrupts[3], 0,
- + "Tx AC3 interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac2_interrupts", CTLFLAG_RD, &sc->tx_interrupts[2], 0,
- + "Tx AC2 interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac1_interrupts", CTLFLAG_RD, &sc->tx_interrupts[1], 0,
- + "Tx AC1 interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac0_interrupts", CTLFLAG_RD, &sc->tx_interrupts[0], 0,
- + "Tx AC0 interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_delay_interrupts", CTLFLAG_RD, &sc->tx_delay_interrupts, 0,
- + "Tx delay interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "pre_tbtt_interrupts", CTLFLAG_RD, &sc->pre_tbtt_interrupts, 0,
- + "Pre-TBTT interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tbtt_interrupts", CTLFLAG_RD, &sc->tbtt_interrupts, 0,
- + "TBTT interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "mcu_cmd_interrupts", CTLFLAG_RD, &sc->mcu_cmd_interrupts, 0,
- + "MCU command interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "auto_wakeup_interrupts", CTLFLAG_RD, &sc->auto_wakeup_interrupts, 0,
- + "auto wakeup interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "gp_timer_interrupts", CTLFLAG_RD, &sc->gp_timer_interrupts, 0,
- + "GP timer interrupts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_mgmt_desc_queued", CTLFLAG_RD, &sc->tx_ring[5].desc_queued, 0,
- + "Tx MGMT descriptors queued");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_mgmt_data_queued", CTLFLAG_RD, &sc->tx_ring[5].data_queued, 0,
- + "Tx MGMT data queued");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_hcca_desc_queued", CTLFLAG_RD, &sc->tx_ring[4].desc_queued, 0,
- + "Tx HCCA descriptors queued");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_hcca_data_queued", CTLFLAG_RD, &sc->tx_ring[4].data_queued, 0,
- + "Tx HCCA data queued");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac3_desc_queued", CTLFLAG_RD, &sc->tx_ring[3].desc_queued, 0,
- + "Tx AC3 descriptors queued");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac3_data_queued", CTLFLAG_RD, &sc->tx_ring[3].data_queued, 0,
- + "Tx AC3 data queued");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac2_desc_queued", CTLFLAG_RD, &sc->tx_ring[2].desc_queued, 0,
- + "Tx AC2 descriptors queued");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac2_data_queued", CTLFLAG_RD, &sc->tx_ring[2].data_queued, 0,
- + "Tx AC2 data queued");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac1_desc_queued", CTLFLAG_RD, &sc->tx_ring[1].desc_queued, 0,
- + "Tx AC1 descriptors queued");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac1_data_queued", CTLFLAG_RD, &sc->tx_ring[1].data_queued, 0,
- + "Tx AC1 data queued");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac0_desc_queued", CTLFLAG_RD, &sc->tx_ring[0].desc_queued, 0,
- + "Tx AC0 descriptors queued");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac0_data_queued", CTLFLAG_RD, &sc->tx_ring[0].data_queued, 0,
- + "Tx AC0 data queued");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_mgmt_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[5], 0,
- + "Tx MGMT data queue full");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_hcca_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[4], 0,
- + "Tx HCCA data queue full");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac3_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[3], 0,
- + "Tx AC3 data queue full");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac2_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[2], 0,
- + "Tx AC2 data queue full");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac1_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[1], 0,
- + "Tx AC1 data queue full");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ac0_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[0], 0,
- + "Tx AC0 data queue full");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_watchdog_timeouts", CTLFLAG_RD, &sc->tx_watchdog_timeouts, 0,
- + "Tx watchdog timeouts");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_defrag_packets", CTLFLAG_RD, &sc->tx_defrag_packets, 0,
- + "Tx defragmented packets");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "no_tx_desc_avail", CTLFLAG_RD, &sc->no_tx_desc_avail, 0,
- + "no Tx descriptors available");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_mbuf_alloc_errors", CTLFLAG_RD, &sc->rx_mbuf_alloc_errors, 0,
- + "Rx mbuf allocation errors");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_mbuf_dmamap_errors", CTLFLAG_RD, &sc->rx_mbuf_dmamap_errors, 0,
- + "Rx mbuf DMA mapping errors");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_queue_0_not_empty", CTLFLAG_RD, &sc->tx_queue_not_empty[0], 0,
- + "Tx queue 0 not empty");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_queue_1_not_empty", CTLFLAG_RD, &sc->tx_queue_not_empty[1], 0,
- + "Tx queue 1 not empty");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_beacons", CTLFLAG_RD, &sc->tx_beacons, 0,
- + "Tx beacons");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_noretryok", CTLFLAG_RD, &sc->tx_noretryok, 0,
- + "Tx successfull without retries");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_retryok", CTLFLAG_RD, &sc->tx_retryok, 0,
- + "Tx successfull with retries");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_failed", CTLFLAG_RD, &sc->tx_failed, 0,
- + "Tx failed");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_underflows", CTLFLAG_RD, &sc->tx_underflows, 0,
- + "Tx underflows");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_zerolen", CTLFLAG_RD, &sc->tx_zerolen, 0,
- + "Tx zero length");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_nonagg", CTLFLAG_RD, &sc->tx_nonagg, 0,
- + "Tx non-aggregated");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_agg", CTLFLAG_RD, &sc->tx_agg, 0,
- + "Tx aggregated");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ampdu", CTLFLAG_RD, &sc->tx_ampdu, 0,
- + "Tx A-MPDU");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_mpdu_zero_density", CTLFLAG_RD, &sc->tx_mpdu_zero_density, 0,
- + "Tx MPDU with zero density");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "tx_ampdu_sessions", CTLFLAG_RD, &sc->tx_ampdu_sessions, 0,
- + "Tx A-MPDU sessions");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_packets", CTLFLAG_RD, &sc->rx_packets, 0,
- + "Rx packets");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_ampdu", CTLFLAG_RD, &sc->rx_ampdu, 0,
- + "Rx A-MPDU");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_ampdu_retries", CTLFLAG_RD, &sc->rx_ampdu_retries, 0,
- + "Rx A-MPDU retries");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_mpdu_zero_density", CTLFLAG_RD, &sc->rx_mpdu_zero_density, 0,
- + "Rx MPDU with zero density");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_ampdu_sessions", CTLFLAG_RD, &sc->rx_ampdu_sessions, 0,
- + "Rx A-MPDU sessions");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_amsdu", CTLFLAG_RD, &sc->rx_amsdu, 0,
- + "Rx A-MSDU");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_crc_errors", CTLFLAG_RD, &sc->rx_crc_errors, 0,
- + "Rx CRC errors");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_phy_errors", CTLFLAG_RD, &sc->rx_phy_errors, 0,
- + "Rx PHY errors");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_false_ccas", CTLFLAG_RD, &sc->rx_false_ccas, 0,
- + "Rx false CCAs");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_plcp_errors", CTLFLAG_RD, &sc->rx_plcp_errors, 0,
- + "Rx PLCP errors");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_dup_packets", CTLFLAG_RD, &sc->rx_dup_packets, 0,
- + "Rx duplicate packets");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_fifo_overflows", CTLFLAG_RD, &sc->rx_fifo_overflows, 0,
- + "Rx FIFO overflows");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_cipher_no_errors", CTLFLAG_RD, &sc->rx_cipher_no_errors, 0,
- + "Rx cipher no errors");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_cipher_icv_errors", CTLFLAG_RD, &sc->rx_cipher_icv_errors, 0,
- + "Rx cipher ICV errors");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_cipher_mic_errors", CTLFLAG_RD, &sc->rx_cipher_mic_errors, 0,
- + "Rx cipher MIC errors");
- +
- + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
- + "rx_cipher_invalid_key_errors", CTLFLAG_RD, &sc->rx_cipher_invalid_key_errors, 0,
- + "Rx cipher invalid key errors");
- + }
- +
- +
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860_amrr.h Sat Jun 4 02:54:23 2011
- ***************
- *** 0 ****
- --- 1,80 ----
- +
- + /*-
- + * Copyright (c) 2009-2010 Alexander Egorenkov <[email protected]>
- + * Copyright (c) 2009 Damien Bergamini <[email protected]>
- + *
- + * 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 _RT2860_AMRR_H_
- + #define _RT2860_AMRR_H_
- +
- + #define RT2860_AMRR_MIN_SUCCESS_THRESHOLD 1
- + #define RT2860_AMRR_MAX_SUCCESS_THRESHOLD 15
- +
- + struct rt2860_amrr
- + {
- + int ntxpath;
- +
- + unsigned int min_success_threshold;
- + unsigned int max_success_threshold;
- +
- + int interval;
- + };
- +
- + struct rt2860_amrr_node
- + {
- + struct rt2860_amrr *amrr;
- +
- + int rate_index;
- +
- + int ticks;
- +
- + unsigned int txcnt;
- + unsigned int success;
- + unsigned int success_threshold;
- + unsigned int recovery;
- + unsigned int retrycnt;
- + };
- +
- + void rt2860_amrr_init(struct rt2860_amrr *amrr, struct ieee80211vap *vap,
- + int ntxpath, int min_success_threshold, int max_success_threshold, int msecs);
- +
- + void rt2860_amrr_cleanup(struct rt2860_amrr *amrr);
- +
- + void rt2860_amrr_node_init(struct rt2860_amrr *amrr,
- + struct rt2860_amrr_node *amrr_node, struct ieee80211_node *ni);
- +
- + int rt2860_amrr_choose(struct ieee80211_node *ni,
- + struct rt2860_amrr_node *amrr_node);
- +
- + static __inline void rt2860_amrr_tx_complete(struct rt2860_amrr_node *amrr_node,
- + int ok, int retries)
- + {
- + amrr_node->txcnt++;
- +
- + if (ok)
- + amrr_node->success++;
- +
- + amrr_node->retrycnt += retries;
- + }
- +
- + static __inline void rt2860_amrr_tx_update(struct rt2860_amrr_node *amrr_node,
- + int txcnt, int success, int retrycnt)
- + {
- + amrr_node->txcnt = txcnt;
- + amrr_node->success = success;
- + amrr_node->retrycnt = retrycnt;
- + }
- +
- + #endif /* #ifndef _RT2860_AMRR_H_ */
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860_debug.h Sat Jun 4 02:54:31 2011
- ***************
- *** 0 ****
- --- 1,53 ----
- +
- + /*-
- + * Copyright (c) 2009-2010 Alexander Egorenkov <[email protected]>
- + * Copyright (c) 2009 Damien Bergamini <[email protected]>
- + *
- + * 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 _RT2860_DEBUG_H_
- + #define _RT2860_DEBUG_H_
- +
- + #ifdef RT2860_DEBUG
- +
- + enum
- + {
- + RT2860_DEBUG_EEPROM = 0x00000001,
- + RT2860_DEBUG_RX = 0x00000002,
- + RT2860_DEBUG_TX = 0x00000004,
- + RT2860_DEBUG_INTR = 0x00000008,
- + RT2860_DEBUG_STATE = 0x00000010,
- + RT2860_DEBUG_CHAN = 0x00000020,
- + RT2860_DEBUG_NODE = 0x00000040,
- + RT2860_DEBUG_KEY = 0x00000080,
- + RT2860_DEBUG_PROT = 0x00000100,
- + RT2860_DEBUG_WME = 0x00000200,
- + RT2860_DEBUG_BEACON = 0x00000400,
- + RT2860_DEBUG_BA = 0x00000800,
- + RT2860_DEBUG_STATS = 0x00001000,
- + RT2860_DEBUG_RATE = 0x00002000,
- + RT2860_DEBUG_PERIODIC = 0x00004000,
- + RT2860_DEBUG_WATCHDOG = 0x00008000,
- + RT2860_DEBUG_ANY = 0xffffffff
- + };
- +
- + #define RT2860_DPRINTF(sc, m, fmt, ...) do { if ((sc)->debug & (m)) printf(fmt, __VA_ARGS__); } while (0)
- +
- + #else
- +
- + #define RT2860_DPRINTF(sc, m, fmt, ...)
- +
- + #endif /* #ifdef RT2860_DEBUG */
- +
- + #endif /* #ifndef _RT2860_DEBUG_H_ */
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860_eeprom.h Sat Jun 4 02:54:39 2011
- ***************
- *** 0 ****
- --- 1,91 ----
- +
- + /*-
- + * Copyright (c) 2009-2010 Alexander Egorenkov <[email protected]>
- + * Copyright (c) 2009 Damien Bergamini <[email protected]>
- + *
- + * 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 _RT2860_EEPROM_H_
- + #define _RT2860_EEPROM_H_
- +
- + #define RT2860_EEPROM_VERSION 0x0002
- + #define RT2860_EEPROM_ADDRESS01 0x0004
- + #define RT2860_EEPROM_ADDRESS23 0x0006
- + #define RT2860_EEPROM_ADDRESS45 0x0008
- + #define RT2860_EEPROM_POWERSAVE_LEVEL 0x0022
- + #define RT2860_EEPROM_ANTENNA 0x0034
- + #define RT2860_EEPROM_NIC_CONFIG 0x0036
- + #define RT2860_EEPROM_COUNTRY 0x0038
- + #define RT2860_EEPROM_RF_FREQ_OFF 0x003a
- + #define RT2860_EEPROM_LED1_OFF 0x003c
- + #define RT2860_EEPROM_LED2_OFF 0x003e
- + #define RT2860_EEPROM_LED3_OFF 0x0040
- + #define RT2860_EEPROM_LNA_GAIN 0x0044
- + #define RT2860_EEPROM_RSSI_OFF_2GHZ_BASE 0x0046
- + #define RT2860_EEPROM_RSSI2_OFF_2GHZ_BASE 0x0048
- + #define RT2860_EEPROM_RSSI_OFF_5GHZ_BASE 0x004a
- + #define RT2860_EEPROM_RSSI2_OFF_5GHZ_BASE 0x004c
- + #define RT2860_EEPROM_TXPOW_RATE_DELTA 0x0050
- + #define RT2860_EEPROM_TXPOW1_2GHZ_BASE 0x0052
- + #define RT2860_EEPROM_TXPOW2_2GHZ_BASE 0x0060
- + #define RT2860_EEPROM_TSSI_2GHZ_BASE 0x006e
- + #define RT2860_EEPROM_TXPOW1_5GHZ_BASE 0x0078
- + #define RT2860_EEPROM_TXPOW2_5GHZ_BASE 0x00a6
- + #define RT2860_EEPROM_TSSI_5GHZ_BASE 0x00d4
- + #define RT2860_EEPROM_TXPOW_RATE_BASE 0x00de
- + #define RT2860_EEPROM_BBP_BASE 0x00f0
- + #define RT3071_EEPROM_RF_BASE 0x0082
- +
- + #define RT2860_EEPROM_RF_2820 1 /* 2.4GHz 2T3R */
- + #define RT2860_EEPROM_RF_2850 2 /* 2.4/5GHz 2T3R */
- + #define RT2860_EEPROM_RF_2720 3 /* 2.4GHz 1T2R */
- + #define RT2860_EEPROM_RF_2750 4 /* 2.4G/5GHz 1T2R */
- + #define RT2860_EEPROM_RF_3020 5 /* 2.4G 1T1R */
- + #define RT2860_EEPROM_RF_2020 6 /* 2.4G B/G */
- + #define RT2860_EEPROM_RF_3021 7 /* 2.4G 1T2R */
- + #define RT2860_EEPROM_RF_3022 8 /* 2.4G 2T2R */
- + #define RT2860_EEPROM_RF_3052 9 /* 2.4G/5G 2T2R */
- + #define RT2860_EEPROM_RF_2853 10 /* 2.4G.5G 3T3R */
- + #define RT2860_EEPROM_RF_3320 11 /* 2.4G 1T1R with PA (RT3350/RT3370/RT3390) */
- + #define RT2860_EEPROM_RF_3322 12 /* 2.4G 2T2R with PA (RT3352/RT3371/RT3372/RT3391/RT3392) */
- + #define RT2860_EEPROM_RF_3053 13 /* 2.4G/5G 3T3R (RT3883/RT3563/RT3573/RT3593/RT3662) */
- + #define RT2860_EEPROM_RF_3853 13 /* 2.4G/5G 3T3R (RT3883/RT3563/RT3573/RT3593/RT3662) */
- +
- + /*
- + * RT2860_EEPROM_NIC_CONFIG flags
- + */
- + #define RT2860_EEPROM_EXT_LNA_5GHZ (1 << 3)
- + #define RT2860_EEPROM_EXT_LNA_2GHZ (1 << 2)
- + #define RT2860_EEPROM_TX_AGC_CNTL (1 << 1)
- + #define RT2860_EEPROM_HW_RADIO_CNTL (1 << 0)
- +
- + #define RT2860_EEPROM_LED_POLARITY (1 << 7)
- + #define RT2860_EEPROM_LED_MODE_MASK 0x7f
- +
- + #define RT2860_EEPROM_LED_CNTL_DEFAULT 0x01
- + #define RT2860_EEPROM_LED1_OFF_DEFAULT 0x5555
- + #define RT2860_EEPROM_LED2_OFF_DEFAULT 0x2221
- + #define RT2860_EEPROM_LED3_OFF_DEFAULT 0xa9f8
- +
- + #define RT2860_EEPROM_RSSI_OFF_MIN -10
- + #define RT2860_EEPROM_RSSI_OFF_MAX 10
- +
- + #define RT2860_EEPROM_TXPOW_2GHZ_MIN 0
- + #define RT2860_EEPROM_TXPOW_2GHZ_MAX 31
- + #define RT2860_EEPROM_TXPOW_2GHZ_DEFAULT 5
- + #define RT2860_EEPROM_TXPOW_5GHZ_MIN -7
- + #define RT2860_EEPROM_TXPOW_5GHZ_MAX 15
- + #define RT2860_EEPROM_TXPOW_5GHZ_DEFAULT 5
- +
- + #endif /* #ifndef _RT2860_EEPROM_H_ */
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860_io.h Sat Jun 4 02:54:45 2011
- ***************
- *** 0 ****
- --- 1,73 ----
- +
- + /*-
- + * Copyright (c) 2009-2010 Alexander Egorenkov <[email protected]>
- + * Copyright (c) 2009 Damien Bergamini <[email protected]>
- + *
- + * 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 _RT2860_IO_H_
- + #define _RT2860_IO_H_
- +
- + #include <dev/ral/rt2860_softc.h>
- +
- + #define RT2860_IO_MCU_CMD_SLEEP 0x30
- + #define RT2860_IO_MCU_CMD_WAKEUP 0x31
- + #define RT2860_IO_MCU_CMD_RADIOOFF 0x35
- + #define RT2860_IO_MCU_CMD_LEDS 0x50
- + #define RT2860_IO_MCU_CMD_LED_BRIGHTNESS 0x51
- + #define RT2860_IO_MCU_CMD_LED1 0x52
- + #define RT2860_IO_MCU_CMD_LED2 0x53
- + #define RT2860_IO_MCU_CMD_LED3 0x54
- + #define RT2860_IO_MCU_CMD_BOOT 0x72
- + #define RT2860_IO_MCU_CMD_BBP 0x80
- + #define RT2860_IO_MCU_CMD_POWERSAVE_LEVEL 0x83
- +
- + void rt2860_io_rf_load_defaults(struct rt2860_softc *sc);
- + uint32_t rt2860_io_mac_read(struct rt2860_softc *sc, uint16_t reg);
- +
- + void rt2860_io_mac_read_multi(struct rt2860_softc *sc,
- + uint16_t reg, void *buf, size_t len);
- +
- + void rt2860_io_mac_write(struct rt2860_softc *sc,
- + uint16_t reg, uint32_t val);
- +
- + void rt2860_io_mac_write_multi(struct rt2860_softc *sc,
- + uint16_t reg, const void *buf, size_t len);
- +
- + void rt2860_io_mac_set_region_4(struct rt2860_softc *sc,
- + uint16_t reg, uint32_t val, size_t len);
- +
- + uint16_t rt2860_io_eeprom_read(struct rt2860_softc *sc, uint16_t addr);
- +
- + void rt2860_io_eeprom_read_multi(struct rt2860_softc *sc,
- + uint16_t addr, void *buf, size_t len);
- +
- + uint8_t rt2860_io_bbp_read(struct rt2860_softc *sc, uint8_t reg);
- +
- + void rt2860_io_bbp_write(struct rt2860_softc *sc, uint8_t reg, uint8_t val);
- +
- + void rt2860_io_rf_write(struct rt2860_softc *sc, uint8_t reg, uint32_t val);
- +
- + int32_t rt2860_io_rf_read(struct rt2860_softc *sc, uint8_t reg);
- +
- + void rt2860_io_mcu_cmd(struct rt2860_softc *sc, uint8_t cmd,
- + uint8_t token, uint16_t arg);
- +
- + int rt2860_io_mcu_cmd_check(struct rt2860_softc *sc, uint8_t cid);
- +
- + int rt2860_io_mcu_load_ucode(struct rt2860_softc *sc,
- + const uint8_t *ucode, size_t len);
- +
- +
- + #endif /* #ifndef _RT2860_IO_H_ */
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860_led.h Sat Jun 4 02:54:50 2011
- ***************
- *** 0 ****
- --- 1,33 ----
- +
- + /*-
- + * Copyright (c) 2009-2010 Alexander Egorenkov <[email protected]>
- + * Copyright (c) 2009 Damien Bergamini <[email protected]>
- + *
- + * 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 _RT2860_LED_H_
- + #define _RT2860_LED_H_
- +
- + #include <dev/ral/rt2860_softc.h>
- +
- + #define RT2860_LED_CMD_RADIO_OFF 0
- + #define RT2860_LED_CMD_RADIO_ON (1 << 5)
- + #define RT2860_LED_CMD_LINK_2GHZ (1 << 6)
- + #define RT2860_LED_CMD_LINK_5GHZ (1 << 7)
- +
- + void rt2860_led_brightness(struct rt2860_softc *sc, uint8_t brightness);
- +
- + void rt2860_led_cmd(struct rt2860_softc *sc, uint8_t cmd);
- +
- + #endif /* #ifndef _RT2860_LED_H_ */
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860_read_eeprom.h Sat Jun 4 02:54:58 2011
- ***************
- *** 0 ****
- --- 1,29 ----
- +
- + /*-
- + * Copyright (c) 2009-2010 Alexander Egorenkov <[email protected]>
- + * Copyright (c) 2009 Damien Bergamini <[email protected]>
- + *
- + * 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 _RT2860_READ_EEPROM_H_
- + #define _RT2860_READ_EEPROM_H_
- +
- + #include <dev/ral/rt2860_softc.h>
- +
- + void rt2860_read_eeprom(struct rt2860_softc *sc);
- +
- + uint32_t rt2860_read_eeprom_txpow_rate_add_delta(uint32_t txpow_rate,
- + int8_t delta);
- +
- + #endif /* #ifndef _RT2860_READ_EEPROM_H_ */
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860_reg.h Sat Jun 4 02:49:07 2011
- ***************
- *** 0 ****
- --- 1,559 ----
- +
- + /*-
- + * Copyright (c) 2009-2010 Alexander Egorenkov <[email protected]>
- + * Copyright (c) 2009 Damien Bergamini <[email protected]>
- + *
- + * 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 _RT2860_REG_H_
- + #define _RT2860_REG_H_
- +
- + #define RT2860_REG_PCI_CFG 0x0000
- + #define RT2860_REG_EEPROM_CSR 0x0004
- + #define RT2860_REG_PCI_MCU_CSR 0x0008
- + #define RT2860_REG_PCI_SYS_CSR 0x000c
- + #define RT2860_REG_PCIE_JTAG 0x0010
- +
- + #define RT2860_REG_SCHDMA_INT_STATUS 0x0200
- + #define RT2860_REG_SCHDMA_INT_MASK 0x0204
- + #define RT2860_REG_SCHDMA_WPDMA_GLO_CFG 0x0208
- + #define RT2860_REG_SCHDMA_WPDMA_RST_IDX 0x020c
- + #define RT2860_REG_SCHDMA_DELAY_INT_CFG 0x0210
- + #define RT2860_REG_SCHDMA_WMM_AIFSN_CFG 0x0214
- + #define RT2860_REG_SCHDMA_WMM_CWMIN_CFG 0x0218
- + #define RT2860_REG_SCHDMA_WMM_CWMAX_CFG 0x021c
- + #define RT2860_REG_SCHDMA_WMM_TXOP0_CFG 0x0220
- + #define RT2860_REG_SCHDMA_WMM_TXOP1_CFG 0x0224
- + #define RT2860_REG_SCHDMA_GPIO_CTRL_CFG 0x0228
- + #define RT2860_REG_SCHDMA_RX_BASE_PTR 0x0290
- + #define RT2860_REG_SCHDMA_RX_MAX_CNT 0x0294
- + #define RT2860_REG_SCHDMA_RX_CALC_IDX 0x0298
- + #define RT2860_REG_SCHDMA_RX_DRX_IDX 0x029c
- + #define RT2860_REG_SCHDMA_TX_BASE_PTR(qid) (0x0230 + (qid) * 16)
- + #define RT2860_REG_SCHDMA_TX_MAX_CNT(qid) (0x0234 + (qid) * 16)
- + #define RT2860_REG_SCHDMA_TX_CTX_IDX(qid) (0x0238 + (qid) * 16)
- + #define RT2860_REG_SCHDMA_TX_DTX_IDX(qid) (0x023c + (qid) * 16)
- + #define RT2860_REG_SCHDMA_US_CYC_CNT 0x02a4
- +
- + #define RT2860_REG_PBF_SYS_CTRL 0x0400
- + #define RT2860_REG_PBF_HOST_CMD 0x0404
- + #define RT2860_REG_PBF_CFG 0x0408
- + #define RT2860_REG_PBF_MAX_PCNT 0x040c
- + #define RT2860_REG_PBF_BUF_CTRL 0x0410
- + #define RT2860_REG_PBF_MCU_INT_STA 0x0414
- + #define RT2860_REG_PBF_MCU_INT_ENA 0x0418
- + #define RT2860_REG_PBF_TX0Q_IO 0x041c
- + #define RT2860_REG_PBF_TX1Q_IO 0x0420
- + #define RT2860_REG_PBF_TX2Q_IO 0x0424
- + #define RT2860_REG_PBF_RX0Q_IO 0x0428
- + #define RT2860_REG_PBF_BCN_OFFSET0 0x042c
- + #define RT2860_REG_PBF_BCN_OFFSET1 0x0430
- + #define RT2860_REG_PBF_TXRXQ_STA 0x0434
- + #define RT2860_REG_PBF_TXRXQ_PCNT 0x0438
- + #define RT2860_REG_PBF_DBG 0x043c
- + #define RT2860_REG_PBF_CAP_CTRL 0x0440
- +
- + #define RT2872_REG_RF_CSR_CFG 0x500
- + #define RT2872_REG_RF_SETTING 0x504
- + #define RT2872_REG_RF_TEST_CONTROL 0x508
- +
- + #define RT2860_REG_MAC_CSR0 0x1000
- + #define RT2860_REG_SYS_CTRL 0x1004
- + #define RT2860_REG_ADDR_DW0 0x1008
- + #define RT2860_REG_ADDR_DW1 0x100c
- + #define RT2860_REG_BSSID_DW0 0x1010
- + #define RT2860_REG_BSSID_DW1 0x1014
- + #define RT2860_REG_MAX_LEN_CFG 0x1018
- + #define RT2860_REG_BBP_CSR_CFG 0x101c
- + #define RT2860_REG_RF_CSR_CFG0 0x1020
- + #define RT2860_REG_LED_CFG 0x102c
- + #define RT2860_REG_AMPDU_MAX_LEN_20M1S 0x1030
- + #define RT2860_REG_AMPDU_MAX_LEN_20M2S 0x1034
- + #define RT2860_REG_AMPDU_MAX_LEN_40M1S 0x1038
- + #define RT2860_REG_AMPDU_MAX_LEN_40M2S 0x103c
- + #define RT2860_REG_AMPDU_BA_WINSIZE 0x1040
- +
- + #define RT2860_REG_XIFS_TIME_CFG 0x1100
- + #define RT2860_REG_BKOFF_SLOT_CFG 0x1104
- + #define RT2860_REG_NAV_TIME_CFG 0x1108
- + #define RT2860_REG_CH_TIME_CFG 0x110c
- + #define RT2860_REG_PBF_LIFE_TIMER 0x1110
- + #define RT2860_REG_BCN_TIME_CFG 0x1114
- + #define RT2860_REG_TBTT_SYNC_CFG 0x1118
- + #define RT2860_REG_TSF_TIMER_DW0 0x111c
- + #define RT2860_REG_TSF_TIMER_DW1 0x1120
- + #define RT2860_REG_TBTT_TIMER 0x1124
- + #define RT2860_REG_INT_TIMER 0x1128
- + #define RT2860_REG_INT_TIMER_EN 0x112c
- + #define RT2860_REG_CH_IDLE_STA 0x1130
- +
- + #define RT2860_REG_STATUS_CFG 0x1200
- + #define RT2860_REG_PWR_PIN_CFG 0x1204
- + #define RT2860_REG_AUTO_WAKEUP_CFG 0x1208
- +
- + #define RT2860_REG_TX_EDCA_AC_CFG(aci) (0x1300 + (aci) * 4)
- + #define RT2860_REG_TX_EDCA_TID_AC_MAP 0x1310
- + #define RT2860_REG_TX_PWR_CFG(ridx) (0x1314 + (ridx) * 4)
- + #define RT2860_REG_TX_PIN_CFG 0x1328
- + #define RT2860_REG_TX_BAND_CFG 0x132c
- + #define RT2860_REG_TX_SW_CFG0 0x1330
- + #define RT2860_REG_TX_SW_CFG1 0x1334
- + #define RT2860_REG_TX_SW_CFG2 0x1338
- + #define RT2860_REG_TX_TXOP_THRES_CFG 0x133c
- + #define RT2860_REG_TX_TXOP_CTRL_CFG 0x1340
- + #define RT2860_REG_TX_RTS_CFG 0x1344
- + #define RT2860_REG_TX_TIMEOUT_CFG 0x1348
- + #define RT2860_REG_TX_RTY_CFG 0x134c
- + #define RT2860_REG_TX_LINK_CFG 0x1350
- + #define RT2860_REG_TX_HT_FBK_CFG0 0x1354
- + #define RT2860_REG_TX_HT_FBK_CFG1 0x1358
- + #define RT2860_REG_TX_LG_FBK_CFG0 0x135c
- + #define RT2860_REG_TX_LG_FBK_CFG1 0x1360
- + #define RT2860_REG_TX_CCK_PROT_CFG 0x1364
- + #define RT2860_REG_TX_OFDM_PROT_CFG 0x1368
- + #define RT2860_REG_TX_MM20_PROT_CFG 0x136c
- + #define RT2860_REG_TX_MM40_PROT_CFG 0x1370
- + #define RT2860_REG_TX_GF20_PROT_CFG 0x1374
- + #define RT2860_REG_TX_GF40_PROT_CFG 0x1378
- + #define RT2860_REG_TX_EXP_CTS_TIME 0x137c
- + #define RT2860_REG_TX_EXP_ACK_TIME 0x1380
- +
- + #define RT2860_REG_RX_FILTER_CFG 0x1400
- + #define RT2860_REG_AUTO_RSP_CFG 0x1404
- + #define RT2860_REG_LEGACY_BASIC_RATE 0x1408
- + #define RT2860_REG_HT_BASIC_RATE 0x140c
- + #define RT2860_REG_HT_CTRL_CFG 0x1410
- + #define RT2860_REG_SIFS_COST_CFG 0x1414
- + #define RT2860_REG_RX_PARSER_CFG 0x1418
- +
- + #define RT2860_REG_TX_SEC_CNT0 0x1500
- + #define RT2860_REG_RX_SEC_CNT0 0x1504
- + #define RT2860_REG_CCMP_FC_MUTE 0x1508
- +
- + #define RT2860_REG_HCCAPSMP_TXOP_HLDR_ADDR0 0x1600
- + #define RT2860_REG_HCCAPSMP_TXOP_HLDR_ADDR1 0x1604
- + #define RT2860_REG_HCCAPSMP_TXOP_HLDR_ET 0x1608
- + #define RT2860_REG_HCCAPSMP_QOS_CFPOLL_RA_DW0 0x160c
- + #define RT2860_REG_HCCAPSMP_QOS_CFPOLL_A1_DW1 0x1610
- + #define RT2860_REG_HCCAPSMP_QOS_CFPOLL_QC 0x1614
- +
- + #define RT2860_REG_RX_STA_CNT0 0x1700
- + #define RT2860_REG_RX_STA_CNT1 0x1704
- + #define RT2860_REG_RX_STA_CNT2 0x1708
- + #define RT2860_REG_TX_STA_CNT0 0x170c
- + #define RT2860_REG_TX_STA_CNT1 0x1710
- + #define RT2860_REG_TX_STA_CNT2 0x1714
- + #define RT2860_REG_TX_STA_FIFO 0x1718
- + #define RT2860_REG_TX_AGG_CNT 0x171c
- + #define RT2860_REG_TX_AGG_CNT0 0x1720
- + #define RT2860_REG_TX_AGG_CNT1 0x1724
- + #define RT2860_REG_TX_AGG_CNT2 0x1728
- + #define RT2860_REG_TX_AGG_CNT3 0x172c
- + #define RT2860_REG_TX_AGG_CNT4 0x1730
- + #define RT2860_REG_TX_AGG_CNT5 0x1734
- + #define RT2860_REG_TX_AGG_CNT6 0x1738
- + #define RT2860_REG_TX_AGG_CNT7 0x173c
- + #define RT2860_REG_TXRX_MPDU_DEN_CNT 0x1740
- +
- + #define RT2860_REG_WCID(wcid) (0x1800 + (wcid) * 8)
- + #define RT2860_REG_PKEY(wcid) (0x4000 + (wcid) * 32)
- + #define RT2860_REG_IVEIV(wcid) (0x6000 + (wcid) * 8)
- + #define RT2860_REG_WCID_ATTR(wcid) (0x6800 + (wcid) * 4)
- + #define RT2860_REG_SKEY(vap, kidx) (0x6c00 + ((vap) * 4 + (kidx)) * 32)
- + #define RT2860_REG_SKEY_MODE(vap) (0x7000 + ((vap) / 2) * 4)
- +
- + #define RT2860_REG_MCU_UCODE_BASE 0x2000
- +
- + #define RT2860_REG_H2M_HOST_CMD 0x0404
- + #define RT2860_REG_H2M_MAILBOX 0x7010
- + #define RT2860_REG_H2M_MAILBOX_CID 0x7014
- + #define RT2860_REG_H2M_MAILBOX_STATUS 0x701c
- + #define RT2860_REG_H2M_MAILBOX_BBP_AGENT 0x7028
- +
- + #define RT2860_REG_BEACON_BASE(vap) (0x7800 + (vap) * 512)
- +
- + /* RT3070 registers */
- + #define RT3070_RF_CSR_CFG 0x0500
- + #define RT3070_EFUSE_CTRL 0x0580
- + #define RT3070_EFUSE_DATA0 0x0590
- + #define RT3070_EFUSE_DATA1 0x0594
- + #define RT3070_EFUSE_DATA2 0x0598
- + #define RT3070_EFUSE_DATA3 0x059c
- + #define RT3090_OSC_CTRL 0x05a4
- + #define RT3070_LDO_CFG0 0x05d4
- + #define RT3070_GPIO_SWITCH 0x05dc
- +
- + #define RT3090_AUX_CTRL 0x010c
- + #define RT3070_OPT_14 0x0114
- +
- + /* possible flags for register RF_CSR_CFG */
- + #define RT3070_RF_KICK (1 << 17)
- + #define RT3070_RF_WRITE (1 << 16)
- +
- + /* possible flags for register EFUSE_CTRL */
- + #define RT3070_SEL_EFUSE (1 << 31)
- + #define RT3070_EFSROM_KICK (1 << 30)
- + #define RT3070_EFSROM_AIN_MASK 0x03ff0000
- + #define RT3070_EFSROM_AIN_SHIFT 16
- + #define RT3070_EFSROM_MODE_MASK 0x000000c0
- + #define RT3070_EFUSE_AOUT_MASK 0x0000003f
- +
- + /* possible flags for RT3020 RF register 1 */
- + #define RT3070_RF_BLOCK (1 << 0)
- + #define RT3070_RX0_PD (1 << 2)
- + #define RT3070_TX0_PD (1 << 3)
- + #define RT3070_RX1_PD (1 << 4)
- + #define RT3070_TX1_PD (1 << 5)
- + #define RT3070_RX2_PD (1 << 6)
- + #define RT3070_TX2_PD (1 << 7)
- +
- + /* possible flags for RT3020 RF register 1 */
- + #define RT3070_RF_BLOCK (1 << 0)
- + #define RT3070_RX0_PD (1 << 2)
- + #define RT3070_TX0_PD (1 << 3)
- + #define RT3070_RX1_PD (1 << 4)
- + #define RT3070_TX1_PD (1 << 5)
- + #define RT3070_RX2_PD (1 << 6)
- + #define RT3070_TX2_PD (1 << 7)
- +
- + /* possible flags for RT3020 RF register 7 */
- + #define RT3070_TUNE (1 << 0)
- +
- + /* possible flags for RT3020 RF register 15 */
- + #define RT3070_TX_LO2 (1 << 3)
- +
- + /* possible flags for RT3020 RF register 17 */
- + #define RT3070_TX_LO1 (1 << 3)
- +
- + /* possible flags for RT3020 RF register 20 */
- + #define RT3070_RX_LO1 (1 << 3)
- +
- + /* possible flags for RT3020 RF register 21 */
- + #define RT3070_RX_LO2 (1 << 3)
- + #define RT3070_RX_CTB (1 << 7)
- +
- + /* possible flags for RT3020 RF register 22 */
- + #define RT3070_BB_LOOPBACK (1 << 0)
- +
- + /* possible flags for RT3053 RF register 1 */
- + #define RT3593_VCO (1 << 0)
- +
- + /* possible flags for RT3053 RF register 2 */
- + #define RT3593_RESCAL (1 << 7)
- +
- + /* possible flags for RT3053 RF register 3 */
- + #define RT3593_VCOCAL (1 << 7)
- +
- + /* possible flags for RT3053 RF register 6 */
- + #define RT3593_VCO_IC (1 << 6)
- +
- + /* possible flags for RT3053 RF register 20 */
- + #define RT3593_LDO_PLL_VC_MASK 0x0e
- + #define RT3593_LDO_RF_VC_MASK 0xe0
- +
- + /* possible flags for RT3053 RF register 22 */
- + #define RT3593_CP_IC_MASK 0xe0
- + #define RT3593_CP_IC_SHIFT 5
- +
- + /* possible flags for RT3053 RF register 46 */
- + #define RT3593_RX_CTB (1 << 5)
- +
- + #define RT3090_DEF_LNA 10
- +
- +
- + #define RT2860_REG_RF_R1 0
- + #define RT2860_REG_RF_R2 1
- + #define RT2860_REG_RF_R3 2
- + #define RT2860_REG_RF_R4 3
- +
- + /*
- + * RT2860_REG_EEPROM_CSR flags
- + */
- + #define RT2860_REG_EERL (1 << 7)
- + #define RT2860_REG_EEDO (1 << 3)
- + #define RT2860_REG_EEDI (1 << 2)
- + #define RT2860_REG_EECS (1 << 1)
- + #define RT2860_REG_EESK (1 << 0)
- + #define RT2860_REG_EEOP_READ 0x6
- +
- + /*
- + * RT2860_REG_SCHDMA_INT_STATUS
- + * RT2860_REG_SCHDMA_INT_MASK flags
- + */
- + #define RT2860_REG_INT_TX_COHERENT (1 << 17)
- + #define RT2860_REG_INT_RX_COHERENT (1 << 16)
- + #define RT2860_REG_INT_GP_TIMER (1 << 15)
- + #define RT2860_REG_INT_AUTO_WAKEUP (1 << 14)
- + #define RT2860_REG_INT_FIFO_STA_FULL (1 << 13)
- + #define RT2860_REG_INT_PRE_TBTT (1 << 12)
- + #define RT2860_REG_INT_TBTT (1 << 11)
- + #define RT2860_REG_INT_TXRX_COHERENT (1 << 10)
- + #define RT2860_REG_INT_MCU_CMD (1 << 9)
- + #define RT2860_REG_INT_TX_MGMT_DONE (1 << 8)
- + #define RT2860_REG_INT_TX_HCCA_DONE (1 << 7)
- + #define RT2860_REG_INT_TX_AC3_DONE (1 << 6)
- + #define RT2860_REG_INT_TX_AC2_DONE (1 << 5)
- + #define RT2860_REG_INT_TX_AC1_DONE (1 << 4)
- + #define RT2860_REG_INT_TX_AC0_DONE (1 << 3)
- + #define RT2860_REG_INT_RX_DONE (1 << 2)
- + #define RT2860_REG_INT_TX_DELAY_DONE (1 << 1)
- + #define RT2860_REG_INT_RX_DELAY_DONE (1 << 0)
- +
- + /*
- + * RT2860_REG_SCHDMA_WPDMA_GLO_CFG flags
- + */
- + #define RT2860_REG_TX_WB_DDONE (1 << 6)
- + #define RT2860_REG_RX_DMA_BUSY (1 << 3)
- + #define RT2860_REG_RX_DMA_ENABLE (1 << 2)
- + #define RT2860_REG_TX_DMA_BUSY (1 << 1)
- + #define RT2860_REG_TX_DMA_ENABLE (1 << 0)
- + #define RT2860_REG_WPDMA_BT_SIZE_SHIFT 4
- + #define RT2860_REG_WPDMA_BT_SIZE16 0
- + #define RT2860_REG_WPDMA_BT_SIZE32 1
- + #define RT2860_REG_WPDMA_BT_SIZE64 2
- + #define RT2860_REG_WPDMA_BT_SIZE128 3
- +
- + /*
- + * RT2860_REG_SCHDMA_WPDMA_RST_IDX flags
- + */
- + #define RT2860_REG_RST_IDX_RX (1 << 16)
- + #define RT2860_REG_RST_IDX_TX_MGMT (1 << 5)
- + #define RT2860_REG_RST_IDX_TX_HCCA (1 << 4)
- + #define RT2860_REG_RST_IDX_TX_AC3 (1 << 3)
- + #define RT2860_REG_RST_IDX_TX_AC2 (1 << 2)
- + #define RT2860_REG_RST_IDX_TX_AC1 (1 << 1)
- + #define RT2860_REG_RST_IDX_TX_AC0 (1 << 0)
- +
- + /*
- + * RT2860_REG_SCHDMA_DELAY_INT_CFG flags
- + */
- + #define RT2860_REG_INT_TX_DELAY_ENABLE (1 << 31)
- + #define RT2860_REG_INT_TX_MAX_PINT_SHIFT 24
- + #define RT2860_REG_INT_TX_MAX_PINT_MASK 0x7
- + #define RT2860_REG_INT_TX_MAX_PTIME_SHIFT 16
- + #define RT2860_REG_INT_TX_MAX_PTIME_MASK 0x8
- + #define RT2860_REG_INT_RX_DELAY_ENABLE (1 << 15)
- + #define RT2860_REG_INT_RX_MAX_PINT_SHIFT 8
- + #define RT2860_REG_INT_RX_MAX_PINT_MASK 0x7
- + #define RT2860_REG_INT_RX_MAX_PTIME_SHIFT 0
- + #define RT2860_REG_INT_RX_MAX_PTIME_MASK 0x8
- +
- + /*
- + * RT2860_REG_PBF_SYS_CTRL flags
- + */
- + #define RT2860_REG_HST_PM_SEL (1 << 16)
- + #define RT2860_REG_MCU_READY (1 << 7)
- + #define RT2860_REG_MCU_RESET (1 << 0)
- +
- + /*
- + * RT2860_REG_PBF_TXRXQ_PCNT flags
- + */
- + #define RT2860_REG_RXQ_PCNT_SHIFT 24
- + #define RT2860_REG_RXQ_PCNT_MASK 0xff
- + #define RT2860_REG_TX2Q_PCNT_SHIFT 16
- + #define RT2860_REG_TX2Q_PCNT_MASK 0xff
- + #define RT2860_REG_TX1Q_PCNT_SHIFT 8
- + #define RT2860_REG_TX1Q_PCNT_MASK 0xff
- + #define RT2860_REG_TX0Q_PCNT_SHIFT 0
- + #define RT2860_REG_TX0Q_PCNT_MASK 0xff
- +
- + /*
- + * RT2860_REG_SYS_CTRL flags
- + */
- + #define RT2860_REG_RX_ENABLE (1 << 3)
- + #define RT2860_REG_TX_ENABLE (1 << 2)
- + #define RT2860_REG_BBP_HRST (1 << 1)
- + #define RT2860_REG_MAC_SRST (1 << 0)
- +
- + /*
- + * RT2872_REG_RF_CSR_CFG flags
- + */
- + #define RT2872_REG_RF_CSR_BUSY (1 << 17)
- + #define RT2872_REG_RF_CSR_KICK (1 << 17)
- + #define RT2872_REG_RF_CSR_WRITE (1 << 16)
- + #define RT2872_REG_RF_ID_SHIFT 8
- + #define RT2872_REG_RF_ID_MASK 0x1f
- + #define RT2872_REG_RF_VAL_SHIFT 0
- + #define RT2872_REG_RF_VAL_MASK 0xff
- +
- + /*
- + * RT2860_REG_BBP_CSR_CFG flags
- + */
- + #define RT2860_REG_BBP_RW_MODE_PARALLEL (1 << 19)
- + #define RT2860_REG_BBP_PAR_DUR (1 << 19)
- + #define RT2860_REG_BBP_CSR_BUSY (1 << 17)
- + #define RT2860_REG_BBP_CSR_KICK (1 << 17)
- + #define RT2860_REG_BBP_CSR_READ (1 << 16)
- + #define RT2860_REG_BBP_REG_SHIFT 8
- + #define RT2860_REG_BBP_REG_MASK 0xff
- + #define RT2860_REG_BBP_VAL_SHIFT 0
- + #define RT2860_REG_BBP_VAL_MASK 0xff
- +
- + /*
- + * RT2860_REG_RF_CSR_CFG0 flags
- + */
- + #define RT2860_REG_RF_BUSY (1 << 31)
- +
- + /*
- + * RT2860_REG_BCN_TIME_CFG flags
- + */
- + #define RT2860_REG_BCN_TX_ENABLE (1 << 20)
- + #define RT2860_REG_TBTT_TIMER_ENABLE (1 << 19)
- + #define RT2860_REG_TSF_TIMER_ENABLE (1 << 16)
- + #define RT2860_REG_TSF_SYNC_MODE_SHIFT 17
- + #define RT2860_REG_TSF_SYNC_MODE_MASK 0x3
- + #define RT2860_REG_TSF_SYNC_MODE_DISABLE 0
- + #define RT2860_REG_TSF_SYNC_MODE_STA 1
- + #define RT2860_REG_TSF_SYNC_MODE_IBSS 2
- + #define RT2860_REG_TSF_SYNC_MODE_HOSTAP 3
- +
- + /*
- + * RT2860_REG_STATUS_CFG flags
- + */
- + #define RT2860_REG_STATUS_RX_BUSY (1 << 1)
- + #define RT2860_REG_STATUS_TX_BUSY (1 << 0)
- +
- + /*
- + * RT2860_REG_TX_PIN_CFG flags
- + */
- + #define RT2860_REG_TRSW_ENABLE (1 << 18)
- + #define RT2860_REG_RFTR_ENABLE (1 << 16)
- + #define RT2860_REG_LNA_PE_G1_ENABLE (1 << 11)
- + #define RT2860_REG_LNA_PE_A1_ENABLE (1 << 10)
- + #define RT2860_REG_LNA_PE_G0_ENABLE (1 << 9)
- + #define RT2860_REG_LNA_PE_A0_ENABLE (1 << 8)
- + #define RT2860_REG_PA_PE_G1_ENABLE (1 << 3)
- + #define RT2860_REG_PA_PE_A1_ENABLE (1 << 2)
- + #define RT2860_REG_PA_PE_G0_ENABLE (1 << 1)
- + #define RT2860_REG_PA_PE_A0_ENABLE (1 << 0)
- +
- + /*
- + * RT2860_REG_TX_BAND_CFG flags
- + */
- + #define RT2860_REG_TX_BAND_BG (1 << 2)
- + #define RT2860_REG_TX_BAND_A (1 << 1)
- + #define RT2860_REG_TX_BAND_HT40_ABOVE (1 << 0)
- + #define RT2860_REG_TX_BAND_HT40_BELOW (0 << 0)
- +
- + /*
- + * RT2860_REG_TX_RTS_CFG flags
- + */
- + #define RT2860_REG_TX_RTS_THRESHOLD_SHIFT 8
- + #define RT2860_REG_TX_RTS_THRESHOLD_MASK 0xffff
- +
- + /*
- + * RT2860_REG_TX_CCK_PROT_CFG
- + * RT2860_REG_TX_OFDM_PROT_CFG
- + * RT2860_REG_TX_MM20_PROT_CFG
- + * RT2860_REG_TX_MM40_PROT_CFG
- + * RT2860_REG_TX_GF20_PROT_CFG
- + * RT2860_REG_TX_GF40_PROT_CFG flags
- + */
- + #define RT2860_REG_RTSTH_ENABLE (1 << 26)
- + #define RT2860_REG_TXOP_ALLOW_GF40 (1 << 25)
- + #define RT2860_REG_TXOP_ALLOW_GF20 (1 << 24)
- + #define RT2860_REG_TXOP_ALLOW_MM40 (1 << 23)
- + #define RT2860_REG_TXOP_ALLOW_MM20 (1 << 22)
- + #define RT2860_REG_TXOP_ALLOW_OFDM (1 << 21)
- + #define RT2860_REG_TXOP_ALLOW_CCK (1 << 20)
- + #define RT2860_REG_TXOP_ALLOW_ALL (0x3f << 20)
- + #define RT2860_REG_PROT_NAV_NONE (0 << 18)
- + #define RT2860_REG_PROT_NAV_SHORT (1 << 18)
- + #define RT2860_REG_PROT_NAV_LONG (2 << 18)
- + #define RT2860_REG_PROT_CTRL_NONE (0 << 16)
- + #define RT2860_REG_PROT_CTRL_RTS_CTS (1 << 16)
- + #define RT2860_REG_PROT_CTRL_CTS (2 << 16)
- + #define RT2860_REG_PROT_PHYMODE_SHIFT 14
- + #define RT2860_REG_PROT_PHYMODE_MASK 0x3
- + #define RT2860_REG_PROT_PHYMODE_CCK 0
- + #define RT2860_REG_PROT_PHYMODE_OFDM 1
- + #define RT2860_REG_PROT_MCS_SHIFT 0
- + #define RT2860_REG_PROT_MCS_MASK 0x7f
- +
- + /*
- + * RT2860_REG_RX_FILTER_CFG flags
- + */
- + #define RT2860_REG_RX_FILTER_DROP_CTRL_RSV (1 << 16)
- + #define RT2860_REG_RX_FILTER_DROP_BAR (1 << 15)
- + #define RT2860_REG_RX_FILTER_DROP_BA (1 << 14)
- + #define RT2860_REG_RX_FILTER_DROP_PSPOLL (1 << 13)
- + #define RT2860_REG_RX_FILTER_DROP_RTS (1 << 12)
- + #define RT2860_REG_RX_FILTER_DROP_CTS (1 << 11)
- + #define RT2860_REG_RX_FILTER_DROP_ACK (1 << 10)
- + #define RT2860_REG_RX_FILTER_DROP_CFEND (1 << 9)
- + #define RT2860_REG_RX_FILTER_DROP_CFACK (1 << 8)
- + #define RT2860_REG_RX_FILTER_DROP_DUPL (1 << 7)
- + #define RT2860_REG_RX_FILTER_DROP_BCAST (1 << 6)
- + #define RT2860_REG_RX_FILTER_DROP_MCAST (1 << 5)
- + #define RT2860_REG_RX_FILTER_DROP_VER_ERR (1 << 4)
- + #define RT2860_REG_RX_FILTER_DROP_NOT_MYBSS (1 << 3)
- + #define RT2860_REG_RX_FILTER_DROP_UC_NOME (1 << 2)
- + #define RT2860_REG_RX_FILTER_DROP_PHY_ERR (1 << 1)
- + #define RT2860_REG_RX_FILTER_DROP_CRC_ERR (1 << 0)
- +
- + /*
- + * RT2860_REG_AUTO_RSP_CFG flags
- + */
- + #define RT2860_REG_CCK_SHORT_ENABLE (1 << 4)
- +
- + /*
- + * RT2860_REG_TX_STA_FIFO flags
- + */
- + #define RT2860_REG_TX_STA_FIFO_MCS_SHIFT 16
- + #define RT2860_REG_TX_STA_FIFO_MCS_MASK 0x7f
- + #define RT2860_REG_TX_STA_FIFO_WCID_SHIFT 8
- + #define RT2860_REG_TX_STA_FIFO_WCID_MASK 0xff
- + #define RT2860_REG_TX_STA_FIFO_PID_SHIFT 1
- + #define RT2860_REG_TX_STA_FIFO_PID_MASK 0xf
- + #define RT2860_REG_TX_STA_FIFO_ACK_REQ (1 << 7)
- + #define RT2860_REG_TX_STA_FIFO_AGG (1 << 6)
- + #define RT2860_REG_TX_STA_FIFO_TX_OK (1 << 5)
- + #define RT2860_REG_TX_STA_FIFO_VALID (1 << 0)
- +
- + /*
- + * RT2860_REG_WCID_ATTR flags
- + */
- + #define RT2860_REG_VAP_SHIFT 4
- + #define RT2860_REG_VAP_MASK 0x7
- + #define RT2860_REG_CIPHER_MODE_SHIFT 1
- + #define RT2860_REG_CIPHER_MODE_MASK 0x7
- + #define RT2860_REG_CIPHER_MODE_NONE 0
- + #define RT2860_REG_CIPHER_MODE_WEP40 1
- + #define RT2860_REG_CIPHER_MODE_WEP104 2
- + #define RT2860_REG_CIPHER_MODE_TKIP 3
- + #define RT2860_REG_CIPHER_MODE_AES_CCMP 4
- + #define RT2860_REG_CIPHER_MODE_CKIP40 5
- + #define RT2860_REG_CIPHER_MODE_CKIP104 6
- + #define RT2860_REG_CIPHER_MODE_CKIP128 7
- + #define RT2860_REG_PKEY_ENABLE (1 << 0)
- +
- + /*
- + * RT2860_REG_H2M_MAILBOX flags
- + */
- + #define RT2860_REG_H2M_BUSY (1 << 24)
- + #define RT2860_REG_H2M_TOKEN_POWERSAVE 1
- + #define RT2860_REG_H2M_TOKEN_RADIOOFF 2
- + #define RT2860_REG_H2M_TOKEN_WAKEUP 3
- + #define RT2860_REG_H2M_TOKEN_NO_INTR 0xff
- +
- + /*
- + * RT2860_REG_H2M_MAILBOX_CID flags
- + */
- + #define RT2860_REG_H2M_CID0_SHIFT 0
- + #define RT2860_REG_H2M_CID1_SHIFT 8
- + #define RT2860_REG_H2M_CID2_SHIFT 16
- + #define RT2860_REG_H2M_CID3_SHIFT 24
- + #define RT2860_REG_H2M_CID_MASK 0xff
- +
- + #endif /* #ifndef _RT2860_REG_H_ */
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860_rf.h Sat Jun 4 02:55:09 2011
- ***************
- *** 0 ****
- --- 1,49 ----
- +
- + /*-
- + * Copyright (c) 2009-2010 Alexander Egorenkov <[email protected]>
- + * Copyright (c) 2009 Damien Bergamini <[email protected]>
- + *
- + * 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 _RT2860_RF_H_
- + #define _RT2860_RF_H_
- +
- + #include <dev/ral/rt2860_softc.h>
- +
- + const char *rt2860_rf_name(int rf_rev);
- +
- + void rt2860_rf_select_chan_group(struct rt2860_softc *sc,
- + struct ieee80211_channel *c);
- +
- + void rt2860_rf_set_chan(struct rt2860_softc *sc,
- + struct ieee80211_channel *c);
- +
- + uint8_t rt3090_rf_read(struct rt2860_softc *sc, uint8_t reg);
- +
- + void rt3090_rf_write(struct rt2860_softc *sc, uint8_t reg, uint8_t val);
- +
- + void rt3090_set_chan(struct rt2860_softc *sc, u_int chan);
- +
- + int rt3090_rf_init(struct rt2860_softc *sc);
- +
- + void rt3090_set_rx_antenna(struct rt2860_softc *, int);
- +
- + void rt3090_rf_wakeup(struct rt2860_softc *sc);
- +
- + int rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target,
- + uint8_t *val);
- +
- + void rt3090_rf_setup(struct rt2860_softc *sc);
- +
- + #endif /* #ifndef _RT2860_RF_H_ */
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860_rxdesc.h Sat Jun 4 02:49:07 2011
- ***************
- *** 0 ****
- --- 1,62 ----
- +
- + /*-
- + * Copyright (c) 2009-2010 Alexander Egorenkov <[email protected]>
- + * Copyright (c) 2009 Damien Bergamini <[email protected]>
- + *
- + * 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 _RT2860_RXDESC_H_
- + #define _RT2860_RXDESC_H_
- +
- + #define RT2860_RXDESC_SDL0_DDONE (1 << 15)
- +
- + #define RT2860_RXDESC_FLAGS_LAST_AMSDU (1 << 19)
- + #define RT2860_RXDESC_FLAGS_CIPHER_ALG (1 << 18)
- + #define RT2860_RXDESC_FLAGS_PLCP_RSSIL (1 << 17)
- + #define RT2860_RXDESC_FLAGS_DECRYPTED (1 << 16)
- + #define RT2860_RXDESC_FLAGS_AMPDU (1 << 15)
- + #define RT2860_RXDESC_FLAGS_L2PAD (1 << 14)
- + #define RT2860_RXDESC_FLAGS_RSSI (1 << 13)
- + #define RT2860_RXDESC_FLAGS_HTC (1 << 12)
- + #define RT2860_RXDESC_FLAGS_AMSDU (1 << 11)
- + #define RT2860_RXDESC_FLAGS_CRC_ERR (1 << 8)
- + #define RT2860_RXDESC_FLAGS_MYBSS (1 << 7)
- + #define RT2860_RXDESC_FLAGS_BCAST (1 << 6)
- + #define RT2860_RXDESC_FLAGS_MCAST (1 << 5)
- + #define RT2860_RXDESC_FLAGS_U2M (1 << 4)
- + #define RT2860_RXDESC_FLAGS_FRAG (1 << 3)
- + #define RT2860_RXDESC_FLAGS_NULL_DATA (1 << 2)
- + #define RT2860_RXDESC_FLAGS_DATA (1 << 1)
- + #define RT2860_RXDESC_FLAGS_BA (1 << 0)
- +
- + #define RT2860_RXDESC_FLAGS_CIPHER_ERR_SHIFT 9
- + #define RT2860_RXDESC_FLAGS_CIPHER_ERR_MASK 0x3
- + #define RT2860_RXDESC_FLAGS_CIPHER_ERR_NONE 0
- + #define RT2860_RXDESC_FLAGS_CIPHER_ERR_ICV 1
- + #define RT2860_RXDESC_FLAGS_CIPHER_ERR_MIC 2
- + #define RT2860_RXDESC_FLAGS_CIPHER_ERR_INVALID_KEY 3
- +
- + #define RT2860_RXDESC_FLAGS_PLCP_SIGNAL_SHIFT 20
- + #define RT2860_RXDESC_FLAGS_PLCP_SIGNAL_MASK 0xfff
- +
- + struct rt2860_rxdesc
- + {
- + uint32_t sdp0;
- + uint16_t sdl1;
- + uint16_t sdl0;
- + uint32_t sdp1;
- + uint32_t flags;
- + } __packed;
- +
- + #endif /* #ifndef _RT2860_RXDESC_H_ */
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860_rxwi.h Sat Jun 4 02:55:20 2011
- ***************
- *** 0 ****
- --- 1,79 ----
- +
- + /*-
- + * Copyright (c) 2009-2010 Alexander Egorenkov <[email protected]>
- + * Copyright (c) 2009 Damien Bergamini <[email protected]>
- + *
- + * 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 _RT2860_RXWI_H_
- + #define _RT2860_RXWI_H_
- +
- + #define RT2860_RXWI_KEYIDX_SHIFT 0
- + #define RT2860_RXWI_KEYIDX_MASK 0x3
- +
- + #define RT2860_RXWI_BSSIDX_SHIFT 2
- + #define RT2860_RXWI_BSSIDX_MASK 0x7
- +
- + #define RT2860_RXWI_UDF_SHIFT 5
- + #define RT2860_RXWI_UDF_MASK 0x7
- +
- + #define RT2860_RXWI_SIZE_SHIFT 0
- + #define RT2860_RXWI_SIZE_MASK 0xfff
- +
- + #define RT2860_RXWI_TID_SHIFT 12
- + #define RT2860_RXWI_TID_MASK 0xf
- +
- + #define RT2860_RXWI_FRAG_SHIFT 0
- + #define RT2860_RXWI_FRAG_MASK 0xf
- +
- + #define RT2860_RXWI_SEQ_SHIFT 4
- + #define RT2860_RXWI_SEQ_MASK 0xfff
- +
- + #define RT2860_RXWI_MCS_SHIFT 0
- + #define RT2860_RXWI_MCS_MASK 0x7f
- + #define RT2860_RXWI_MCS_SHOTPRE (1 << 3)
- +
- + #define RT2860_RXWI_BW_SHIFT 7
- + #define RT2860_RXWI_BW_MASK 0x1
- + #define RT2860_RXWI_BW_20 0
- + #define RT2860_RXWI_BW_40 1
- +
- + #define RT2860_RXWI_SHORTGI_SHIFT 0
- + #define RT2860_RXWI_SHORTGI_MASK 0x1
- +
- + #define RT2860_RXWI_STBC_SHIFT 1
- + #define RT2860_RXWI_STBC_MASK 0x3
- +
- + #define RT2860_RXWI_PHYMODE_SHIFT 6
- + #define RT2860_RXWI_PHYMODE_MASK 0x3
- + #define RT2860_RXWI_PHYMODE_CCK 0
- + #define RT2860_RXWI_PHYMODE_OFDM 1
- + #define RT2860_RXWI_PHYMODE_HT_MIXED 2
- + #define RT2860_RXWI_PHYMODE_HT_GF 3
- +
- + struct rt2860_rxwi
- + {
- + uint8_t wcid;
- + uint8_t udf_bssidx_keyidx;
- + uint16_t tid_size;
- + uint16_t seq_frag;
- + uint8_t bw_mcs;
- + uint8_t phymode_stbc_shortgi;
- + uint8_t rssi[3];
- + uint8_t reserved1;
- + uint8_t snr[2];
- + uint16_t reserved2;
- + } __packed;
- +
- + #endif /* #ifndef _RT2860_RXWI_H_ */
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860_txdesc.h Sat Jun 4 02:49:07 2011
- ***************
- *** 0 ****
- --- 1,48 ----
- +
- + /*-
- + * Copyright (c) 2009-2010 Alexander Egorenkov <[email protected]>
- + * Copyright (c) 2009 Damien Bergamini <[email protected]>
- + *
- + * 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 _RT2860_TXDESC_H_
- + #define _RT2860_TXDESC_H_
- +
- + #define RT2860_TXDESC_SDL1_BURST (1 << 15)
- + #define RT2860_TXDESC_SDL1_LASTSEG (1 << 14)
- +
- + #define RT2860_TXDESC_SDL0_DDONE (1 << 15)
- + #define RT2860_TXDESC_SDL0_LASTSEG (1 << 14)
- +
- + #define RT2860_TXDESC_FLAGS_SHIFT 0
- + #define RT2860_TXDESC_FLAGS_MASK 0xf9
- + #define RT2860_TXDESC_FLAGS_WI_VALID (1 << 0)
- +
- + #define RT2860_TXDESC_QSEL_SHIFT 1
- + #define RT2860_TXDESC_QSEL_MASK 0x3
- + #define RT2860_TXDESC_QSEL_MGMT 0
- + #define RT2860_TXDESC_QSEL_HCCA 1
- + #define RT2860_TXDESC_QSEL_EDCA 2
- +
- + struct rt2860_txdesc
- + {
- + uint32_t sdp0;
- + uint16_t sdl1;
- + uint16_t sdl0;
- + uint32_t sdp1;
- + uint8_t reserved[3];
- + uint8_t qsel_flags;
- + } __packed;
- +
- + #endif /* #ifndef _RT2860_TXDESC_H_ */
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860_txwi.h Sat Jun 4 02:49:07 2011
- ***************
- *** 0 ****
- --- 1,92 ----
- +
- + /*-
- + * Copyright (c) 2009-2010 Alexander Egorenkov <[email protected]>
- + * Copyright (c) 2009 Damien Bergamini <[email protected]>
- + *
- + * 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 _RT2860_TXWI_H_
- + #define _RT2860_TXWI_H_
- +
- + #define RT2860_TXWI_FLAGS_SHIFT 0
- + #define RT2860_TXWI_FLAGS_MASK 0x1f
- + #define RT2860_TXWI_FLAGS_AMPDU (1 << 4)
- + #define RT2860_TXWI_FLAGS_TS (1 << 3)
- + #define RT2860_TXWI_FLAGS_CFACK (1 << 2)
- + #define RT2860_TXWI_FLAGS_MIMOPS (1 << 1)
- + #define RT2860_TXWI_FLAGS_FRAG (1 << 0)
- +
- + #define RT2860_TXWI_MPDU_DENSITY_SHIFT 5
- + #define RT2860_TXWI_MPDU_DENSITY_MASK 0x7
- +
- + #define RT2860_TXWI_TXOP_SHIFT 0
- + #define RT2860_TXWI_TXOP_MASK 0x3
- + #define RT2860_TXWI_TXOP_HT 0
- + #define RT2860_TXWI_TXOP_PIFS 1
- + #define RT2860_TXWI_TXOP_SIFS 2
- + #define RT2860_TXWI_TXOP_BACKOFF 3
- +
- + #define RT2860_TXWI_MCS_SHIFT 0
- + #define RT2860_TXWI_MCS_MASK 0x7f
- + #define RT2860_TXWI_MCS_SHOTPRE (1 << 3)
- +
- + #define RT2860_TXWI_BW_SHIFT 7
- + #define RT2860_TXWI_BW_MASK 0x1
- + #define RT2860_TXWI_BW_20 0
- + #define RT2860_TXWI_BW_40 1
- +
- + #define RT2860_TXWI_SHORTGI_SHIFT 0
- + #define RT2860_TXWI_SHORTGI_MASK 0x1
- +
- + #define RT2860_TXWI_STBC_SHIFT 1
- + #define RT2860_TXWI_STBC_MASK 0x3
- +
- + #define RT2860_TXWI_IFS_SHIFT 3
- + #define RT2860_TXWI_IFS_MASK 0x1
- +
- + #define RT2860_TXWI_PHYMODE_SHIFT 6
- + #define RT2860_TXWI_PHYMODE_MASK 0x3
- + #define RT2860_TXWI_PHYMODE_CCK 0
- + #define RT2860_TXWI_PHYMODE_OFDM 1
- + #define RT2860_TXWI_PHYMODE_HT_MIXED 2
- + #define RT2860_TXWI_PHYMODE_HT_GF 3
- +
- + #define RT2860_TXWI_XFLAGS_SHIFT 0
- + #define RT2860_TXWI_XFLAGS_MASK 0x3
- + #define RT2860_TXWI_XFLAGS_NSEQ (1 << 1)
- + #define RT2860_TXWI_XFLAGS_ACK (1 << 0)
- +
- + #define RT2860_TXWI_BAWIN_SIZE_SHIFT 2
- + #define RT2860_TXWI_BAWIN_SIZE_MASK 0x3f
- +
- + #define RT2860_TXWI_MPDU_LEN_SHIFT 0
- + #define RT2860_TXWI_MPDU_LEN_MASK 0xfff
- +
- + #define RT2860_TXWI_PID_SHIFT 12
- + #define RT2860_TXWI_PID_MASK 0xf
- +
- + struct rt2860_txwi
- + {
- + uint8_t mpdu_density_flags;
- + uint8_t txop;
- + uint8_t bw_mcs;
- + uint8_t phymode_ifs_stbc_shortgi;
- + uint8_t bawin_size_xflags;
- + uint8_t wcid;
- + uint16_t pid_mpdu_len;
- + uint32_t iv;
- + uint32_t eiv;
- + } __packed;
- +
- + #endif /* #ifndef _RT2860_TXWI_H_ */
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860_ucode.h Sat Jun 4 02:49:07 2011
- ***************
- *** 0 ****
- --- 1,2104 ----
- +
- + /*
- + Copyright (c) 2007, Ralink Technology Corporation
- + All rights reserved.
- +
- + Redistribution. Redistribution and use in binary form, without
- + modification, are permitted provided that the following conditions are
- + met:
- +
- + * Redistributions must reproduce the above copyright notice and the
- + following disclaimer in the documentation and/or other materials
- + provided with the distribution.
- + * Neither the name of Ralink Technology Corporation nor the names of its
- + suppliers may be used to endorse or promote products derived from this
- + software without specific prior written permission.
- + * No reverse engineering, decompilation, or disassembly of this software
- + is permitted.
- +
- + Limited patent license. Ralink Technology Corporation grants a world-wide,
- + royalty-free, non-exclusive license under patents it now or hereafter
- + owns or controls to make, have made, use, import, offer to sell and
- + sell ("Utilize") this software, but solely to the extent that any
- + such patent is necessary to Utilize the software alone, or in
- + combination with an operating system licensed under an approved Open
- + Source license as listed by the Open Source Initiative at
- + http://opensource.org/licenses. The patent license shall not apply to
- + any other combinations which include this software. No hardware per
- + se is licensed hereunder.
- +
- + DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
- + COPYRIGHT OWNER 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.
- + */
- +
- + #ifndef _RT2860_UCODE_H_
- + #define _RT2860_UCODE_H_
- +
- + /*
- + * RT2860 microcode v26
- + */
- + static const uint8_t rt2860_ucode[] =
- + {
- + 0x02, 0x03, 0x5E, 0x02,
- + 0x02, 0xB1, 0x22, 0x22,
- + 0xFF, 0xFF, 0xFF, 0x02,
- + 0x01, 0x82, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0x02,
- + 0x00, 0x1E, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0x02,
- + 0x01, 0x33, 0xC0, 0xE0,
- + 0xC0, 0xF0, 0xC0, 0x83,
- + 0xC0, 0x82, 0xC0, 0xD0,
- + 0x75, 0xD0, 0x18, 0xC2,
- + 0xAF, 0x30, 0x45, 0x03,
- + 0x12, 0x10, 0x09, 0x90,
- + 0x04, 0x16, 0xE0, 0x30,
- + 0xE3, 0x03, 0x74, 0x08,
- + 0xF0, 0x90, 0x04, 0x14,
- + 0xE0, 0x20, 0xE7, 0x03,
- + 0x02, 0x00, 0xCB, 0x74,
- + 0x80, 0xF0, 0x90, 0x70,
- + 0x12, 0xE0, 0xF5, 0x2F,
- + 0x90, 0x04, 0x04, 0xE0,
- + 0x24, 0xCF, 0x60, 0x30,
- + 0x14, 0x60, 0x42, 0x24,
- + 0xE2, 0x60, 0x47, 0x14,
- + 0x60, 0x55, 0x24, 0x21,
- + 0x70, 0x60, 0xE5, 0x55,
- + 0x24, 0xFE, 0x60, 0x07,
- + 0x14, 0x60, 0x08, 0x24,
- + 0x02, 0x70, 0x08, 0x7D,
- + 0x01, 0x80, 0x28, 0x7D,
- + 0x02, 0x80, 0x24, 0x90,
- + 0x70, 0x10, 0xE0, 0xF5,
- + 0x50, 0x85, 0x2F, 0x40,
- + 0xD2, 0x01, 0x80, 0x3E,
- + 0xE5, 0x55, 0x64, 0x03,
- + 0x60, 0x04, 0xE5, 0x55,
- + 0x70, 0x04, 0x7D, 0x02,
- + 0x80, 0x09, 0x85, 0x2F,
- + 0x41, 0xD2, 0x02, 0x80,
- + 0x29, 0xAD, 0x55, 0xAF,
- + 0x2F, 0x12, 0x02, 0x8D,
- + 0x80, 0x20, 0x90, 0x70,
- + 0x10, 0xE0, 0xF5, 0x47,
- + 0x90, 0x70, 0x11, 0xE0,
- + 0xF5, 0x44, 0x12, 0x10,
- + 0x25, 0x80, 0x06, 0x90,
- + 0x70, 0x10, 0xE0, 0xF5,
- + 0x45, 0xE4, 0xFD, 0xAF,
- + 0x2F, 0x12, 0x02, 0x8D,
- + 0xD2, 0x04, 0x90, 0x70,
- + 0x13, 0xE4, 0xF0, 0xD2,
- + 0xAF, 0xD0, 0xD0, 0xD0,
- + 0x82, 0xD0, 0x83, 0xD0,
- + 0xF0, 0xD0, 0xE0, 0x32,
- + 0x90, 0x70, 0x2A, 0xE0,
- + 0x30, 0xE1, 0x53, 0xC2,
- + 0xAF, 0x90, 0x70, 0x28,
- + 0xE0, 0x90, 0x10, 0x1C,
- + 0xF0, 0x90, 0x70, 0x29,
- + 0xE0, 0x90, 0x10, 0x1D,
- + 0xF0, 0x90, 0x70, 0x2A,
- + 0xE0, 0x90, 0x10, 0x1E,
- + 0xF0, 0x90, 0x10, 0x1C,
- + 0xE0, 0xF5, 0x30, 0x90,
- + 0x10, 0x1E, 0xE0, 0x20,
- + 0xE1, 0xF3, 0x90, 0x10,
- + 0x1C, 0xE0, 0x90, 0x70,
- + 0x28, 0xF0, 0x90, 0x10,
- + 0x1D, 0xE0, 0x90, 0x70,
- + 0x29, 0xF0, 0x90, 0x10,
- + 0x1E, 0xE0, 0x90, 0x70,
- + 0x2A, 0xF0, 0x30, 0x4A,
- + 0x0D, 0x90, 0x70, 0x24,
- + 0xE0, 0x44, 0x01, 0xF0,
- + 0x90, 0x02, 0x2C, 0x74,
- + 0xFF, 0xF0, 0xC2, 0x05,
- + 0xD2, 0xAF, 0x22, 0xC0,
- + 0xE0, 0xC0, 0xF0, 0xC0,
- + 0x83, 0xC0, 0x82, 0xC0,
- + 0xD0, 0xE8, 0xC0, 0xE0,
- + 0xE9, 0xC0, 0xE0, 0xEA,
- + 0xC0, 0xE0, 0xEB, 0xC0,
- + 0xE0, 0xEC, 0xC0, 0xE0,
- + 0xED, 0xC0, 0xE0, 0xEE,
- + 0xC0, 0xE0, 0xEF, 0xC0,
- + 0xE0, 0xC2, 0xAF, 0x30,
- + 0x45, 0x03, 0x12, 0x10,
- + 0x12, 0xD2, 0xAF, 0xD0,
- + 0xE0, 0xFF, 0xD0, 0xE0,
- + 0xFE, 0xD0, 0xE0, 0xFD,
- + 0xD0, 0xE0, 0xFC, 0xD0,
- + 0xE0, 0xFB, 0xD0, 0xE0,
- + 0xFA, 0xD0, 0xE0, 0xF9,
- + 0xD0, 0xE0, 0xF8, 0xD0,
- + 0xD0, 0xD0, 0x82, 0xD0,
- + 0x83, 0xD0, 0xF0, 0xD0,
- + 0xE0, 0x32, 0xC0, 0xE0,
- + 0xC0, 0xF0, 0xC0, 0x83,
- + 0xC0, 0x82, 0xC0, 0xD0,
- + 0x75, 0xD0, 0x10, 0xC2,
- + 0xAF, 0x30, 0x45, 0x03,
- + 0x12, 0x10, 0x0C, 0x30,
- + 0x58, 0x0A, 0xE5, 0x54,
- + 0x60, 0x04, 0x15, 0x54,
- + 0x80, 0x02, 0xC2, 0x58,
- + 0x30, 0x59, 0x0A, 0xE5,
- + 0x50, 0x60, 0x04, 0x15,
- + 0x50, 0x80, 0x02, 0xC2,
- + 0x59, 0xD5, 0x53, 0x07,
- + 0x30, 0x60, 0x04, 0x15,
- + 0x46, 0xD2, 0x04, 0x30,
- + 0x45, 0x03, 0x12, 0x10,
- + 0x0F, 0xC2, 0x8D, 0xD2,
- + 0xAF, 0xD0, 0xD0, 0xD0,
- + 0x82, 0xD0, 0x83, 0xD0,
- + 0xF0, 0xD0, 0xE0, 0x32,
- + 0x12, 0x02, 0xD3, 0x30,
- + 0x45, 0x03, 0x12, 0x10,
- + 0x03, 0x30, 0x01, 0x06,
- + 0x20, 0x09, 0x03, 0x12,
- + 0x10, 0x1C, 0x30, 0x02,
- + 0x06, 0x20, 0x0A, 0x03,
- + 0x12, 0x10, 0x1F, 0x30,
- + 0x03, 0x06, 0x20, 0x0B,
- + 0x03, 0x12, 0x10, 0x1F,
- + 0x30, 0x04, 0x06, 0x20,
- + 0x0C, 0x03, 0x12, 0x10,
- + 0x22, 0x20, 0x13, 0x09,
- + 0x20, 0x11, 0x06, 0xE5,
- + 0x2B, 0x45, 0x2C, 0x60,
- + 0x03, 0xD3, 0x80, 0x01,
- + 0xC3, 0x92, 0xA9, 0x12,
- + 0x02, 0xEC, 0x80, 0xBF,
- + 0xC2, 0x43, 0xD2, 0x45,
- + 0xE4, 0xF5, 0x20, 0xF5,
- + 0x21, 0xF5, 0x53, 0xF5,
- + 0x46, 0xF5, 0x2B, 0xF5,
- + 0x2C, 0xC2, 0x42, 0xF5,
- + 0x51, 0xF5, 0x52, 0xF5,
- + 0x55, 0x90, 0x04, 0x18,
- + 0x74, 0x80, 0xF0, 0x90,
- + 0x04, 0x1A, 0x74, 0x08,
- + 0xF0, 0xC2, 0x19, 0xC2,
- + 0x18, 0xC2, 0x1A, 0x22,
- + 0xC8, 0xEF, 0xC8, 0xE6,
- + 0xFA, 0x08, 0xE6, 0x4A,
- + 0x60, 0x0C, 0xC8, 0xEF,
- + 0xC8, 0x08, 0xE6, 0x16,
- + 0x18, 0x70, 0x01, 0x16,
- + 0xC3, 0x22, 0xED, 0x24,
- + 0xFF, 0xFD, 0xEC, 0x34,
- + 0xFF, 0xC8, 0xEF, 0xC8,
- + 0xF6, 0x08, 0xC6, 0xED,
- + 0xC6, 0xD3, 0x22, 0xD0,
- + 0x83, 0xD0, 0x82, 0xF8,
- + 0xE4, 0x93, 0x70, 0x12,
- + 0x74, 0x01, 0x93, 0x70,
- + 0x0D, 0xA3, 0xA3, 0x93,
- + 0xF8, 0x74, 0x01, 0x93,
- + 0xF5, 0x82, 0x88, 0x83,
- + 0xE4, 0x73, 0x74, 0x02,
- + 0x93, 0x68, 0x60, 0xEF,
- + 0xA3, 0xA3, 0xA3, 0x80,
- + 0xDF, 0xEF, 0xF4, 0x60,
- + 0x1F, 0xE4, 0xFE, 0x12,
- + 0x03, 0x6A, 0xE0, 0xB4,
- + 0xFF, 0x12, 0x12, 0x03,
- + 0x6A, 0xEF, 0xF0, 0x74,
- + 0x1C, 0x2E, 0xF5, 0x82,
- + 0xE4, 0x34, 0x70, 0xF5,
- + 0x83, 0xED, 0xF0, 0x22,
- + 0x0E, 0xBE, 0x04, 0xE3,
- + 0x22, 0xC0, 0xE0, 0xC0,
- + 0xF0, 0xC0, 0x83, 0xC0,
- + 0x82, 0xC0, 0xD0, 0x75,
- + 0xD0, 0x08, 0xC2, 0xAF,
- + 0x30, 0x45, 0x03, 0x12,
- + 0x10, 0x06, 0xD2, 0xAF,
- + 0xD0, 0xD0, 0xD0, 0x82,
- + 0xD0, 0x83, 0xD0, 0xF0,
- + 0xD0, 0xE0, 0x32, 0xC2,
- + 0xAF, 0x12, 0x00, 0x06,
- + 0x12, 0x02, 0x14, 0x12,
- + 0x03, 0x1C, 0xE4, 0xF5,
- + 0x22, 0xF5, 0x47, 0x90,
- + 0x04, 0x00, 0x74, 0x80,
- + 0xF0, 0xD2, 0xAF, 0x22,
- + 0x30, 0x45, 0x03, 0x12,
- + 0x10, 0x15, 0xE5, 0x20,
- + 0x70, 0x03, 0x20, 0x10,
- + 0x03, 0x30, 0x11, 0x03,
- + 0x43, 0x87, 0x01, 0x22,
- + 0xC0, 0x2A, 0x74, 0x03,
- + 0xC0, 0xE0, 0xC0, 0x82,
- + 0xC0, 0x83, 0x75, 0x2A,
- + 0x0A, 0x22, 0xC0, 0x2A,
- + 0x74, 0x03, 0xC0, 0xE0,
- + 0xC0, 0x82, 0xC0, 0x83,
- + 0x75, 0x2A, 0x18, 0x22,
- + 0x75, 0x89, 0x02, 0xE4,
- + 0xF5, 0x8C, 0xF5, 0x8A,
- + 0xF5, 0x88, 0xF5, 0xB8,
- + 0xF5, 0xE8, 0x75, 0x90,
- + 0x18, 0xD2, 0x8C, 0x75,
- + 0xA8, 0x05, 0x22, 0xCE,
- + 0xEF, 0xCE, 0xEE, 0x60,
- + 0x08, 0x7F, 0xFF, 0x12,
- + 0x03, 0x80, 0x1E, 0x80,
- + 0xF5, 0x22, 0xC8, 0xEF,
- + 0xC8, 0xE6, 0x60, 0x03,
- + 0x16, 0xC3, 0x22, 0xED,
- + 0x14, 0xF6, 0xD3, 0x22,
- + 0xC8, 0xEF, 0xC8, 0xE6,
- + 0x60, 0x06, 0x16, 0xE6,
- + 0x24, 0xFF, 0xB3, 0x22,
- + 0xC3, 0x22, 0x78, 0x7F,
- + 0xE4, 0xF6, 0xD8, 0xFD,
- + 0x75, 0x81, 0x5F, 0x02,
- + 0x01, 0xD0, 0x74, 0x14,
- + 0x2E, 0xF5, 0x82, 0xE4,
- + 0x34, 0x70, 0xF5, 0x83,
- + 0x22, 0xEF, 0x90, 0x03,
- + 0x7E, 0x93, 0x90, 0x03,
- + 0x00, 0x73, 0x0A, 0x18,
- + 0xEF, 0x60, 0x03, 0x1F,
- + 0x80, 0xFA, 0x22, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0xFF,
- + 0xFF, 0xFF, 0xFF, 0x02,
- + 0x10, 0x28, 0x02, 0x10,
- + 0x3B, 0x02, 0x10, 0x3C,
- + 0x02, 0x12, 0xB8, 0x02,
- + 0x12, 0xB9, 0x02, 0x13,
- + 0x3E, 0x02, 0x13, 0x3F,
- + 0xC3, 0x22, 0xFF, 0xFF,
- + 0x02, 0x16, 0x56, 0x02,
- + 0x17, 0x6B, 0x02, 0x14,
- + 0x2A, 0x02, 0x13, 0x40,
- + 0x30, 0x05, 0x06, 0x20,
- + 0x0D, 0x03, 0x12, 0x00,
- + 0xD8, 0x30, 0x06, 0x06,
- + 0x20, 0x0E, 0x03, 0x12,
- + 0x18, 0x5E, 0x22, 0x22,
- + 0x90, 0x04, 0x14, 0xE0,
- + 0x20, 0xE7, 0x03, 0x02,
- + 0x12, 0xB7, 0x90, 0x70,
- + 0x12, 0xE0, 0xF5, 0x56,
- + 0x90, 0x04, 0x04, 0xE0,
- + 0x12, 0x02, 0x67, 0x11,
- + 0x4E, 0x30, 0x11, 0x25,
- + 0x31, 0x10, 0x87, 0x33,
- + 0x10, 0xAA, 0x34, 0x10,
- + 0xC3, 0x35, 0x11, 0x57,
- + 0x50, 0x11, 0x7B, 0x51,
- + 0x11, 0x84, 0x52, 0x11,
- + 0x84, 0x53, 0x11, 0x84,
- + 0x54, 0x11, 0xC5, 0x55,
- + 0x11, 0xDC, 0x70, 0x12,
- + 0x07, 0x71, 0x12, 0x34,
- + 0x72, 0x12, 0x5E, 0x80,
- + 0x12, 0x81, 0x83, 0x00,
- + 0x00, 0x12, 0xB7, 0x75,
- + 0x24, 0x05, 0x75, 0x25,
- + 0xDC, 0x90, 0x70, 0x9F,
- + 0x74, 0x12, 0xF0, 0xD2,
- + 0x18, 0xD2, 0x61, 0x75,
- + 0x35, 0x0D, 0xE4, 0x90,
- + 0x70, 0x13, 0xF0, 0xE5,
- + 0x56, 0xF4, 0x70, 0x03,
- + 0x02, 0x12, 0xB7, 0x02,
- + 0x12, 0xAA, 0xC2, 0x18,
- + 0x90, 0x01, 0x14, 0xE0,
- + 0x54, 0xFD, 0xF0, 0xE4,
- + 0x90, 0x70, 0x13, 0xF0,
- + 0xE5, 0x56, 0xF4, 0x70,
- + 0x03, 0x02, 0x12, 0xB7,
- + 0x02, 0x12, 0xAA, 0xE5,
- + 0x55, 0x64, 0x02, 0x70,
- + 0x37, 0x90, 0x70, 0x10,
- + 0xE0, 0x60, 0x08, 0x90,
- + 0x01, 0x0D, 0x74, 0x09,
- + 0xF0, 0x80, 0x25, 0xE5,
- + 0x34, 0x14, 0x60, 0x0A,
- + 0x14, 0x60, 0x0F, 0x14,
- + 0x60, 0x14, 0x24, 0x03,
- + 0x70, 0x16, 0x90, 0x01,
- + 0x0D, 0x74, 0x08, 0xF0,
- + 0x80, 0x0E, 0x90, 0x01,
- + 0x0D, 0x74, 0x0B, 0xF0,
- + 0x80, 0x06, 0x90, 0x01,
- + 0x0D, 0x74, 0x1B, 0xF0,
- + 0x7D, 0x01, 0x80, 0x02,
- + 0x7D, 0x02, 0xAF, 0x56,
- + 0x12, 0x02, 0x8D, 0x90,
- + 0x70, 0x11, 0xE0, 0x24,
- + 0xFF, 0x92, 0x1B, 0x90,
- + 0x04, 0x14, 0x74, 0x80,
- + 0xF0, 0xE4, 0x90, 0x70,
- + 0x13, 0xF0, 0xE5, 0x56,
- + 0xF4, 0x70, 0x03, 0x02,
- + 0x12, 0xB7, 0x02, 0x12,
- + 0xAA, 0x20, 0x02, 0x03,
- + 0x30, 0x03, 0x1D, 0x7D,
- + 0x02, 0xAF, 0x56, 0x12,
- + 0x02, 0x8D, 0x90, 0x04,
- + 0x14, 0x74, 0x80, 0xF0,
- + 0xE4, 0x90, 0x70, 0x13,
- + 0xF0, 0xE5, 0x56, 0xF4,
- + 0x70, 0x03, 0x02, 0x12,
- + 0xB7, 0x02, 0x12, 0xAA,
- + 0x85, 0x56, 0x41, 0xD2,
- + 0x02, 0x22, 0x90, 0x70,
- + 0x11, 0xE0, 0x24, 0xFF,
- + 0x92, 0x1B, 0x22, 0x90,
- + 0x70, 0x10, 0xE0, 0x54,
- + 0x7F, 0x64, 0x02, 0x60,
- + 0x03, 0x02, 0x12, 0xB7,
- + 0x90, 0x70, 0x11, 0xE0,
- + 0x64, 0x08, 0x60, 0x08,
- + 0xE0, 0x64, 0x20, 0x60,
- + 0x03, 0x02, 0x12, 0xB7,
- + 0x75, 0x4E, 0x03, 0x75,
- + 0x4F, 0x20, 0x22, 0x90,
- + 0x70, 0x11, 0xE0, 0x24,
- + 0xFF, 0x92, 0x47, 0x22,
- + 0x90, 0x04, 0x04, 0xE0,
- + 0x25, 0xE0, 0x24, 0x5D,
- + 0xF5, 0x57, 0x90, 0x70,
- + 0x10, 0xE0, 0xFF, 0x74,
- + 0x47, 0x25, 0x57, 0xF8,
- + 0xC6, 0xEF, 0xC6, 0x90,
- + 0x70, 0x11, 0xE0, 0xFF,
- + 0x74, 0x48, 0x25, 0x57,
- + 0xF8, 0xC6, 0xEF, 0xC6,
- + 0xE4, 0xFD, 0xAF, 0x56,
- + 0x12, 0x02, 0x8D, 0x90,
- + 0x04, 0x14, 0x74, 0x80,
- + 0xF0, 0xE4, 0x90, 0x70,
- + 0x13, 0xF0, 0xE5, 0x56,
- + 0xF4, 0x70, 0x03, 0x02,
- + 0x12, 0xB7, 0x02, 0x12,
- + 0xAA, 0xE5, 0x47, 0xB4,
- + 0x07, 0x08, 0x90, 0x70,
- + 0x11, 0xE0, 0x54, 0x07,
- + 0xF5, 0x26, 0xE4, 0xFD,
- + 0xAF, 0x56, 0x12, 0x02,
- + 0x8D, 0xD2, 0x04, 0x22,
- + 0x90, 0x70, 0x10, 0xE0,
- + 0xFE, 0x90, 0x70, 0x11,
- + 0xE0, 0xFD, 0xED, 0xF8,
- + 0xE6, 0xF5, 0x57, 0xFD,
- + 0xAF, 0x56, 0x12, 0x02,
- + 0x8D, 0x90, 0x04, 0x14,
- + 0x74, 0x80, 0xF0, 0xE4,
- + 0x90, 0x70, 0x13, 0xF0,
- + 0xE5, 0x56, 0xF4, 0x70,
- + 0x03, 0x02, 0x12, 0xB7,
- + 0x02, 0x12, 0xAA, 0x90,
- + 0x70, 0x10, 0xE0, 0xFE,
- + 0x90, 0x70, 0x11, 0xE0,
- + 0xFD, 0xED, 0xF5, 0x82,
- + 0x8E, 0x83, 0xE0, 0xF5,
- + 0x57, 0xFD, 0xAF, 0x56,
- + 0x12, 0x02, 0x8D, 0x90,
- + 0x04, 0x14, 0x74, 0x80,
- + 0xF0, 0xE4, 0x90, 0x70,
- + 0x13, 0xF0, 0xE5, 0x56,
- + 0xF4, 0x70, 0x03, 0x02,
- + 0x12, 0xB7, 0x80, 0x76,
- + 0xE4, 0xF5, 0x4E, 0xF5,
- + 0x4F, 0x75, 0x26, 0xFF,
- + 0xC2, 0x19, 0xC2, 0x18,
- + 0xC2, 0x1A, 0x75, 0x34,
- + 0xFF, 0xAD, 0x57, 0xAF,
- + 0x56, 0x12, 0x02, 0x8D,
- + 0x90, 0x04, 0x14, 0x74,
- + 0x80, 0xF0, 0xE4, 0x90,
- + 0x70, 0x13, 0xF0, 0xE5,
- + 0x56, 0xF4, 0x60, 0x5B,
- + 0x80, 0x4C, 0x90, 0x70,
- + 0x10, 0xE0, 0x24, 0xFF,
- + 0x92, 0x4A, 0xD2, 0x05,
- + 0xAD, 0x57, 0xAF, 0x56,
- + 0x12, 0x02, 0x8D, 0x90,
- + 0x04, 0x14, 0x74, 0x80,
- + 0xF0, 0xE4, 0x90, 0x70,
- + 0x13, 0xF0, 0xE5, 0x56,
- + 0xF4, 0x60, 0x38, 0x80,
- + 0x29, 0x90, 0x70, 0x10,
- + 0xE0, 0xF5, 0x34, 0xD3,
- + 0x94, 0x00, 0x40, 0x07,
- + 0x90, 0x01, 0x0D, 0xE0,
- + 0x54, 0xFB, 0xF0, 0xAD,
- + 0x57, 0xAF, 0x56, 0x12,
- + 0x02, 0x8D, 0x90, 0x04,
- + 0x14, 0x74, 0x80, 0xF0,
- + 0xE4, 0x90, 0x70, 0x13,
- + 0xF0, 0xE5, 0x56, 0xF4,
- + 0x60, 0x0D, 0x90, 0x70,
- + 0x25, 0xE0, 0x44, 0x01,
- + 0xF0, 0x90, 0x02, 0x2C,
- + 0x74, 0xFF, 0xF0, 0x22,
- + 0x22, 0xE5, 0x53, 0x60,
- + 0x03, 0x02, 0x13, 0x3D,
- + 0xE5, 0x4F, 0x45, 0x4E,
- + 0x60, 0x08, 0xE5, 0x4F,
- + 0x15, 0x4F, 0x70, 0x02,
- + 0x15, 0x4E, 0xA2, 0x19,
- + 0xE4, 0x33, 0x90, 0x70,
- + 0x90, 0xF0, 0xA2, 0x18,
- + 0xE4, 0x33, 0xA3, 0xF0,
- + 0x30, 0x19, 0x4D, 0x90,
- + 0x70, 0x98, 0x74, 0x23,
- + 0xF0, 0xA3, 0xE5, 0x25,
- + 0xF0, 0xE5, 0x24, 0xA3,
- + 0xF0, 0x7F, 0x35, 0x7D,
- + 0x32, 0x12, 0x03, 0x42,
- + 0x50, 0x09, 0x90, 0x10,
- + 0x04, 0xE0, 0x54, 0xF7,
- + 0xF0, 0xD2, 0x06, 0xE5,
- + 0x35, 0xD3, 0x94, 0x10,
- + 0x40, 0x1E, 0x30, 0x1A,
- + 0x1B, 0xC2, 0x1A, 0xA2,
- + 0x18, 0x92, 0x19, 0x20,
- + 0x19, 0x12, 0x90, 0x04,
- + 0x09, 0xE0, 0x54, 0xDD,
- + 0xF0, 0x90, 0x10, 0x04,
- + 0xE0, 0x44, 0x08, 0xF0,
- + 0xC2, 0x61, 0xD2, 0x03,
- + 0xE5, 0x35, 0xB4, 0x0B,
- + 0x14, 0xD2, 0x03, 0x22,
- + 0xE4, 0xF5, 0x35, 0xA2,
- + 0x18, 0x92, 0x19, 0x30,
- + 0x19, 0x07, 0x90, 0x04,
- + 0x09, 0xE0, 0x44, 0x22,
- + 0xF0, 0x22, 0x22, 0x22,
- + 0xC2, 0x4B, 0xC2, 0x4C,
- + 0xE5, 0x44, 0x12, 0x02,
- + 0x67, 0x13, 0x62, 0x00,
- + 0x13, 0xF5, 0x04, 0x13,
- + 0xF1, 0x08, 0x13, 0xCC,
- + 0x10, 0x13, 0x76, 0x20,
- + 0x13, 0x96, 0x60, 0x13,
- + 0xA7, 0xA0, 0x00, 0x00,
- + 0x13, 0xF7, 0x85, 0x48,
- + 0x43, 0x85, 0x4A, 0x42,
- + 0x85, 0x4C, 0x5E, 0xE5,
- + 0x47, 0x64, 0x06, 0x60,
- + 0x03, 0x02, 0x13, 0xF7,
- + 0x80, 0x1B, 0xE5, 0x48,
- + 0xC4, 0x54, 0x0F, 0xF5,
- + 0x43, 0xE5, 0x4A, 0xC4,
- + 0x54, 0x0F, 0xF5, 0x42,
- + 0xE5, 0x4C, 0xC4, 0x54,
- + 0x0F, 0xF5, 0x5E, 0xE5,
- + 0x47, 0x64, 0x06, 0x70,
- + 0x66, 0x53, 0x43, 0x0F,
- + 0x80, 0x61, 0x85, 0x49,
- + 0x43, 0x85, 0x4B, 0x42,
- + 0x85, 0x4D, 0x5E, 0xE5,
- + 0x47, 0x64, 0x06, 0x70,
- + 0x52, 0x80, 0x1B, 0xE5,
- + 0x49, 0xC4, 0x54, 0x0F,
- + 0xF5, 0x43, 0xE5, 0x4B,
- + 0xC4, 0x54, 0x0F, 0xF5,
- + 0x42, 0xE5, 0x4D, 0xC4,
- + 0x54, 0x0F, 0xF5, 0x5E,
- + 0xE5, 0x47, 0x64, 0x06,
- + 0x70, 0x35, 0xE5, 0x43,
- + 0x54, 0x0F, 0x44, 0x10,
- + 0xF5, 0x43, 0x80, 0x2B,
- + 0xE5, 0x47, 0xB4, 0x04,
- + 0x06, 0x53, 0x5E, 0xFB,
- + 0x75, 0x42, 0x09, 0xE5,
- + 0x47, 0xB4, 0x05, 0x06,
- + 0x43, 0x5E, 0x04, 0x75,
- + 0x42, 0x09, 0xE5, 0x47,
- + 0xB4, 0x06, 0x10, 0xE5,
- + 0x43, 0x54, 0x0F, 0x44,
- + 0x30, 0xF5, 0x43, 0x80,
- + 0x06, 0xD2, 0x4B, 0x80,
- + 0x02, 0xD2, 0x4C, 0xE4,
- + 0xF5, 0x38, 0xE5, 0x42,
- + 0xC4, 0x54, 0xF0, 0xFF,
- + 0xE5, 0x43, 0x54, 0x0F,
- + 0x4F, 0xF5, 0x5F, 0x90,
- + 0x70, 0x44, 0xF0, 0xA3,
- + 0xE5, 0x5E, 0xF0, 0xA3,
- + 0xE5, 0x4A, 0xF0, 0xA3,
- + 0xE5, 0x48, 0xF0, 0xA3,
- + 0xE5, 0x4C, 0xF0, 0xA3,
- + 0xE5, 0x44, 0xF0, 0xA3,
- + 0xE5, 0x42, 0xF0, 0xA3,
- + 0xE5, 0x43, 0xF0, 0xD2,
- + 0x60, 0x22, 0xE5, 0x47,
- + 0x60, 0x10, 0x24, 0xC0,
- + 0x70, 0x03, 0x12, 0x16,
- + 0x36, 0x12, 0x14, 0x3F,
- + 0xC2, 0xAF, 0xC2, 0x04,
- + 0xD2, 0xAF, 0x22, 0xC2,
- + 0xAF, 0x90, 0x04, 0x14,
- + 0xE0, 0x54, 0x0E, 0x60,
- + 0x04, 0xD2, 0x1C, 0x80,
- + 0x08, 0xE5, 0x4E, 0x45,
- + 0x4F, 0x24, 0xFF, 0x92,
- + 0x1C, 0xD2, 0xAF, 0x90,
- + 0x04, 0x14, 0xE0, 0xA2,
- + 0xE4, 0x92, 0x1D, 0x74,
- + 0x1E, 0xF0, 0xE5, 0x5F,
- + 0x54, 0x0F, 0xF5, 0x2D,
- + 0xE5, 0x38, 0x70, 0x13,
- + 0x30, 0x1C, 0x05, 0xE5,
- + 0x5F, 0x20, 0xE5, 0x0B,
- + 0x30, 0x1D, 0x19, 0xE5,
- + 0x5F, 0x54, 0x30, 0xFF,
- + 0xBF, 0x30, 0x11, 0xE5,
- + 0x38, 0x70, 0x05, 0x75,
- + 0x38, 0x0C, 0x80, 0x02,
- + 0x15, 0x38, 0xD2, 0x6C,
- + 0xD2, 0x6D, 0x80, 0x0F,
- + 0xE5, 0x5F, 0x30, 0xE6,
- + 0x06, 0xC2, 0x6C, 0xD2,
- + 0x6D, 0x80, 0x04, 0xD2,
- + 0x6C, 0xC2, 0x6D, 0xE5,
- + 0x47, 0x64, 0x03, 0x70,
- + 0x21, 0x30, 0x4B, 0x06,
- + 0xC2, 0x6C, 0xD2, 0x6D,
- + 0x80, 0x18, 0xE5, 0x38,
- + 0x70, 0x03, 0x30, 0x4C,
- + 0x11, 0xC2, 0x4C, 0xE5,
- + 0x38, 0x70, 0x05, 0x75,
- + 0x38, 0x07, 0x80, 0x02,
- + 0x15, 0x38, 0xD2, 0x6C,
- + 0xD2, 0x6D, 0x90, 0x70,
- + 0x46, 0xE5, 0x2D, 0xF0,
- + 0x20, 0x69, 0x07, 0xE5,
- + 0x5E, 0x20, 0xE0, 0x02,
- + 0xB2, 0x68, 0x20, 0x6B,
- + 0x07, 0xE5, 0x5E, 0x20,
- + 0xE1, 0x02, 0xB2, 0x6A,
- + 0x20, 0x6D, 0x07, 0xE5,
- + 0x5E, 0x20, 0xE2, 0x02,
- + 0xB2, 0x6C, 0x90, 0x70,
- + 0x47, 0xE5, 0x2D, 0xF0,
- + 0x75, 0x2E, 0x40, 0x20,
- + 0x69, 0x04, 0xA2, 0x68,
- + 0x80, 0x15, 0x30, 0x68,
- + 0x06, 0xE5, 0x46, 0xA2,
- + 0xE3, 0x80, 0x0C, 0xE5,
- + 0x46, 0x54, 0xF0, 0xFF,
- + 0xBF, 0xF0, 0x03, 0xD3,
- + 0x80, 0x01, 0xC3, 0x92,
- + 0x73, 0x92, 0x72, 0x20,
- + 0x6B, 0x04, 0xA2, 0x6A,
- + 0x80, 0x15, 0x30, 0x6A,
- + 0x06, 0xE5, 0x46, 0xA2,
- + 0xE3, 0x80, 0x0C, 0xE5,
- + 0x46, 0x54, 0xF0, 0xFF,
- + 0xBF, 0xF0, 0x03, 0xD3,
- + 0x80, 0x01, 0xC3, 0x92,
- + 0x75, 0x92, 0x74, 0x20,
- + 0x6D, 0x04, 0xA2, 0x6C,
- + 0x80, 0x15, 0x30, 0x6C,
- + 0x06, 0xE5, 0x46, 0xA2,
- + 0xE3, 0x80, 0x0C, 0xE5,
- + 0x46, 0x54, 0xF0, 0xFF,
- + 0xBF, 0xF0, 0x03, 0xD3,
- + 0x80, 0x01, 0xC3, 0x92,
- + 0x71, 0x92, 0x70, 0x90,
- + 0x10, 0x2F, 0xE5, 0x2E,
- + 0xF0, 0xE5, 0x47, 0x64,
- + 0x06, 0x70, 0x46, 0x90,
- + 0x02, 0x29, 0xE0, 0x54,
- + 0xFE, 0xF0, 0xE5, 0x43,
- + 0xC4, 0x54, 0x0F, 0x14,
- + 0x60, 0x14, 0x24, 0xFE,
- + 0x60, 0x1F, 0x24, 0x03,
- + 0x60, 0x03, 0x02, 0x16,
- + 0x35, 0x90, 0x02, 0x28,
- + 0xE0, 0x30, 0x47, 0x0D,
- + 0x80, 0x07, 0x90, 0x02,
- + 0x28, 0xE0, 0x20, 0x47,
- + 0x04, 0x54, 0xFE, 0xF0,
- + 0x22, 0x44, 0x01, 0xF0,
- + 0x22, 0xE5, 0x46, 0x30,
- + 0xE3, 0x04, 0x7F, 0x01,
- + 0x80, 0x02, 0x7F, 0x00,
- + 0x90, 0x02, 0x28, 0xE0,
- + 0x54, 0xFE, 0x4F, 0xF0,
- + 0x22, 0xE5, 0x47, 0x64,
- + 0x07, 0x60, 0x03, 0x02,
- + 0x16, 0x35, 0xF5, 0x27,
- + 0x90, 0x02, 0x29, 0xE0,
- + 0x54, 0xFC, 0xF0, 0xE5,
- + 0x26, 0x14, 0x60, 0x26,
- + 0x14, 0x60, 0x2E, 0x14,
- + 0x60, 0x36, 0x24, 0x03,
- + 0x70, 0x5F, 0xE5, 0x46,
- + 0x13, 0x13, 0x13, 0x54,
- + 0x1F, 0x75, 0xF0, 0x03,
- + 0x84, 0xAF, 0xF0, 0x20,
- + 0x47, 0x04, 0x7E, 0x01,
- + 0x80, 0x02, 0x7E, 0x00,
- + 0xEF, 0x6E, 0x24, 0xFF,
- + 0x80, 0x02, 0xA2, 0x47,
- + 0x92, 0x39, 0xA2, 0x47,
- + 0xB3, 0x92, 0x38, 0x80,
- + 0x3F, 0xE5, 0x46, 0x30,
- + 0xE3, 0x03, 0xD3, 0x80,
- + 0x27, 0xC3, 0x80, 0x24,
- + 0xE5, 0x46, 0x30, 0xE3,
- + 0x0D, 0x54, 0x70, 0xC3,
- + 0x94, 0x60, 0x50, 0x06,
- + 0x7E, 0x00, 0x7F, 0x01,
- + 0x80, 0x04, 0x7E, 0x00,
- + 0x7F, 0x00, 0x20, 0x47,
- + 0x04, 0x7D, 0x01, 0x80,
- + 0x02, 0x7D, 0x00, 0xEF,
- + 0x6D, 0x4E, 0x24, 0xFF,
- + 0x92, 0x38, 0xA2, 0x47,
- + 0xB3, 0x92, 0x39, 0x80,
- + 0x07, 0xA2, 0x47, 0xB3,
- + 0x92, 0x38, 0x92, 0x39,
- + 0x90, 0x02, 0x28, 0xE0,
- + 0x54, 0xFC, 0x45, 0x27,
- + 0xF0, 0x22, 0xE4, 0x90,
- + 0x02, 0x29, 0xF0, 0x30,
- + 0x47, 0x04, 0xAF, 0x45,
- + 0x80, 0x04, 0xE5, 0x45,
- + 0xF4, 0xFF, 0x90, 0x02,
- + 0x28, 0xEF, 0xF0, 0x22,
- + 0x8F, 0x50, 0xD2, 0x59,
- + 0x22, 0x8F, 0x54, 0xD2,
- + 0x58, 0x22, 0xE4, 0xF5,
- + 0x30, 0xC2, 0xAF, 0xE5,
- + 0x51, 0x14, 0x60, 0x4A,
- + 0x14, 0x60, 0x6A, 0x24,
- + 0x02, 0x60, 0x03, 0x02,
- + 0x17, 0x4C, 0xD2, 0x59,
- + 0x75, 0x55, 0x01, 0x20,
- + 0x19, 0x1C, 0x90, 0x02,
- + 0x08, 0xE0, 0x54, 0xFE,
- + 0xF0, 0xE0, 0x20, 0xE1,
- + 0x23, 0x90, 0x04, 0x34,
- + 0xE0, 0xB4, 0x02, 0x1C,
- + 0xA3, 0xE0, 0xB4, 0x02,
- + 0x17, 0xA3, 0xE0, 0xB4,
- + 0x02, 0x12, 0x7F, 0x20,
- + 0x12, 0x16, 0x4C, 0x90,
- + 0x10, 0x04, 0xE0, 0x54,
- + 0xF3, 0xF0, 0x75, 0x51,
- + 0x01, 0x02, 0x17, 0x4C,
- + 0xE5, 0x50, 0x70, 0x06,
- + 0x75, 0x30, 0x03, 0x02,
- + 0x17, 0x4C, 0x90, 0x12,
- + 0x00, 0xE0, 0x54, 0x03,
- + 0x70, 0x15, 0x7F, 0x20,
- + 0x12, 0x16, 0x4C, 0x20,
- + 0x19, 0x07, 0x90, 0x02,
- + 0x08, 0xE0, 0x54, 0xFB,
- + 0xF0, 0x75, 0x51, 0x02,
- + 0x02, 0x17, 0x4C, 0xE5,
- + 0x50, 0x70, 0x02, 0x80,
- + 0x7A, 0x20, 0x19, 0x0F,
- + 0x90, 0x02, 0x08, 0xE0,
- + 0x20, 0xE3, 0x6C, 0x90,
- + 0x04, 0x37, 0xE0, 0x64,
- + 0x22, 0x70, 0x64, 0x90,
- + 0x12, 0x04, 0x74, 0x0A,
- + 0xF0, 0x30, 0x1B, 0x11,
- + 0x90, 0x13, 0x28, 0xE0,
- + 0x54, 0xF0, 0xF0, 0xA3,
- + 0xE0, 0x54, 0xF0, 0xF0,
- + 0xA3, 0xE0, 0x54, 0xFA,
- + 0xF0, 0x20, 0x19, 0x07,
- + 0x90, 0x04, 0x01, 0xE0,
- + 0x44, 0x10, 0xF0, 0xE5,
- + 0x34, 0xF4, 0x90, 0x04,
- + 0x01, 0x60, 0x06, 0xE0,
- + 0x54, 0xFB, 0xF0, 0x80,
- + 0x04, 0xE0, 0x54, 0xF9,
- + 0xF0, 0x20, 0x19, 0x07,
- + 0x90, 0x12, 0x04, 0xE0,
- + 0x44, 0x04, 0xF0, 0xE5,
- + 0x34, 0xF4, 0x60, 0x14,
- + 0x90, 0x01, 0x0D, 0xE0,
- + 0xF5, 0x33, 0xE5, 0x34,
- + 0xD3, 0x94, 0x02, 0x40,
- + 0x07, 0x90, 0x12, 0x04,
- + 0xE0, 0x54, 0xFD, 0xF0,
- + 0x75, 0x30, 0x01, 0x75,
- + 0x55, 0x02, 0xE4, 0xF5,
- + 0x51, 0x80, 0x09, 0xE5,
- + 0x50, 0x70, 0x05, 0x75,
- + 0x30, 0x03, 0xF5, 0x51,
- + 0xE5, 0x30, 0x60, 0x18,
- + 0xC2, 0x01, 0xE4, 0xF5,
- + 0x51, 0xC2, 0x59, 0x20,
- + 0x19, 0x0E, 0xAD, 0x30,
- + 0xAF, 0x40, 0x12, 0x18,
- + 0x2A, 0xE5, 0x30, 0xB4,
- + 0x03, 0x02, 0xD2, 0x03,
- + 0xD2, 0xAF, 0x22, 0xC2,
- + 0xAF, 0x30, 0x01, 0x0E,
- + 0xE4, 0xF5, 0x51, 0xC2,
- + 0x59, 0xC2, 0x01, 0x7D,
- + 0x02, 0xAF, 0x40, 0x12,
- + 0x18, 0x2A, 0xE5, 0x52,
- + 0x14, 0x60, 0x55, 0x14,
- + 0x60, 0x2F, 0x24, 0x02,
- + 0x60, 0x03, 0x02, 0x18,
- + 0x27, 0xE5, 0x34, 0xF4,
- + 0x60, 0x23, 0xE5, 0x34,
- + 0xD3, 0x94, 0x02, 0x40,
- + 0x16, 0x90, 0x12, 0x04,
- + 0xE0, 0x44, 0x02, 0xF0,
- + 0x90, 0x01, 0x0D, 0xE0,
- + 0x20, 0xE3, 0x03, 0x02,
- + 0x18, 0x27, 0x7F, 0x50,
- + 0x12, 0x16, 0x51, 0x75,
- + 0x52, 0x02, 0x75, 0x55,
- + 0x03, 0xE5, 0x34, 0xF4,
- + 0x60, 0x0A, 0xE5, 0x54,
- + 0x70, 0x69, 0x90, 0x01,
- + 0x0D, 0xE5, 0x33, 0xF0,
- + 0x90, 0x12, 0x04, 0xE0,
- + 0x54, 0xFB, 0xF0, 0x7F,
- + 0x20, 0x12, 0x16, 0x51,
- + 0x75, 0x52, 0x01, 0x75,
- + 0x55, 0x03, 0x80, 0x4F,
- + 0xE5, 0x54, 0x70, 0x4B,
- + 0x90, 0x04, 0x01, 0xE0,
- + 0x44, 0x0E, 0xF0, 0x20,
- + 0x19, 0x04, 0xE0, 0x54,
- + 0xEF, 0xF0, 0x90, 0x13,
- + 0x28, 0xE0, 0x44, 0x0F,
- + 0xF0, 0xA3, 0xE0, 0x44,
- + 0x0F, 0xF0, 0xA3, 0xE0,
- + 0x44, 0x05, 0xF0, 0x90,
- + 0x12, 0x04, 0x74, 0x03,
- + 0xF0, 0x20, 0x19, 0x07,
- + 0x90, 0x02, 0x08, 0xE0,
- + 0x44, 0x05, 0xF0, 0x90,
- + 0x10, 0x04, 0xE0, 0x44,
- + 0x0C, 0xF0, 0xE4, 0xF5,
- + 0x52, 0xF5, 0x55, 0x30,
- + 0x02, 0x0B, 0xC2, 0x02,
- + 0x7D, 0x01, 0xAF, 0x41,
- + 0x12, 0x18, 0x2A, 0x80,
- + 0x02, 0xC2, 0x03, 0xD2,
- + 0xAF, 0x22, 0xEF, 0xF4,
- + 0x60, 0x2D, 0xE4, 0xFE,
- + 0x74, 0x14, 0x2E, 0xF5,
- + 0x82, 0xE4, 0x34, 0x70,
- + 0xF5, 0x83, 0xE0, 0xB4,
- + 0xFF, 0x19, 0x74, 0x14,
- + 0x2E, 0xF5, 0x82, 0xE4,
- + 0x34, 0x70, 0xF5, 0x83,
- + 0xEF, 0xF0, 0x74, 0x1C,
- + 0x2E, 0xF5, 0x82, 0xE4,
- + 0x34, 0x70, 0xF5, 0x83,
- + 0xED, 0xF0, 0x22, 0x0E,
- + 0xBE, 0x04, 0xD5, 0x22,
- + 0x22, 0x22, 0x20, 0x19,
- + 0x03, 0x02, 0x19, 0x0F,
- + 0x90, 0x70, 0x80, 0xE0,
- + 0x04, 0xF0, 0x90, 0x04,
- + 0x37, 0xE0, 0x30, 0xE5,
- + 0x03, 0x02, 0x19, 0x0B,
- + 0x90, 0x04, 0x28, 0xE0,
- + 0xF5, 0x31, 0xA3, 0xE0,
- + 0xF5, 0x30, 0xF5, 0x32,
- + 0xE4, 0xF5, 0x37, 0x90,
- + 0x70, 0x81, 0xE0, 0x04,
- + 0xF0, 0x90, 0x70, 0x82,
- + 0xE0, 0x04, 0xF0, 0xE5,
- + 0x32, 0x75, 0xF0, 0x80,
- + 0xA4, 0x24, 0x00, 0xFF,
- + 0xE5, 0xF0, 0x34, 0x80,
- + 0xFE, 0xE5, 0x30, 0x65,
- + 0x32, 0x70, 0x05, 0xFC,
- + 0x7D, 0x18, 0x80, 0x04,
- + 0x7C, 0x00, 0x7D, 0x00,
- + 0xEF, 0x2D, 0xFF, 0xEE,
- + 0x3C, 0xFE, 0x12, 0x19,
- + 0x10, 0x50, 0x25, 0x90,
- + 0x70, 0x83, 0xE0, 0x04,
- + 0xF0, 0x90, 0x01, 0x14,
- + 0xE0, 0x44, 0x02, 0xF0,
- + 0xE0, 0x30, 0xE1, 0x06,
- + 0x90, 0x70, 0x92, 0x74,
- + 0x45, 0xF0, 0x90, 0x70,
- + 0x93, 0xE0, 0x04, 0xF0,
- + 0x90, 0x04, 0x01, 0xE0,
- + 0x90, 0x70, 0x94, 0xF0,
- + 0xE5, 0x32, 0x65, 0x31,
- + 0x60, 0x10, 0xE4, 0x25,
- + 0x32, 0xFF, 0xE4, 0x34,
- + 0x80, 0x8F, 0x82, 0xF5,
- + 0x83, 0xE0, 0xF5, 0x32,
- + 0x80, 0x97, 0x90, 0x04,
- + 0x10, 0x74, 0x01, 0xF0,
- + 0x90, 0x04, 0x28, 0xE5,
- + 0x31, 0xF0, 0xA3, 0xE5,
- + 0x30, 0xF0, 0x90, 0x04,
- + 0x11, 0x74, 0x01, 0xF0,
- + 0x02, 0x18, 0x6A, 0xC2,
- + 0x06, 0xD2, 0x1A, 0x22,
- + 0x90, 0x70, 0x84, 0xE5,
- + 0x37, 0xF0, 0xC3, 0x94,
- + 0x06, 0x50, 0x19, 0x8F,
- + 0x82, 0x8E, 0x83, 0xE0,
- + 0xB4, 0xFF, 0x07, 0x05,
- + 0x37, 0xE4, 0xF5, 0x36,
- + 0x80, 0x59, 0xE4, 0xF5,
- + 0x37, 0x8F, 0x82, 0x8E,
- + 0x83, 0xF0, 0x80, 0x4F,
- + 0xE5, 0x36, 0x75, 0xF0,
- + 0x06, 0x84, 0x74, 0x08,
- + 0x25, 0xF0, 0xF5, 0x82,
- + 0xE4, 0x34, 0x10, 0xF5,
- + 0x83, 0xE0, 0xFD, 0x8F,
- + 0x82, 0x8E, 0x83, 0xE0,
- + 0xFC, 0x6D, 0x70, 0x30,
- + 0x90, 0x70, 0x88, 0xE0,
- + 0x04, 0xF0, 0xA3, 0xE0,
- + 0xFD, 0xD3, 0x95, 0x37,
- + 0x40, 0x02, 0x80, 0x02,
- + 0xAD, 0x37, 0x90, 0x70,
- + 0x89, 0xED, 0xF0, 0x05,
- + 0x37, 0x05, 0x36, 0xE5,
- + 0x36, 0x75, 0xF0, 0x06,
- + 0x84, 0x74, 0x8A, 0x25,
- + 0xF0, 0xF5, 0x82, 0xE4,
- + 0x34, 0x70, 0xF5, 0x83,
- + 0xEC, 0xF0, 0x80, 0x03,
- + 0xE4, 0xF5, 0x37, 0x0F,
- + 0xBF, 0x00, 0x01, 0x0E,
- + 0xEF, 0x54, 0x7F, 0x60,
- + 0x0A, 0xE5, 0x37, 0xC3,
- + 0x94, 0x4E, 0x50, 0x03,
- + 0x02, 0x19, 0x10, 0xE5,
- + 0x37, 0xB4, 0x4E, 0x03,
- + 0xD3, 0x80, 0x01, 0xC3,
- + 0x22, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x00, 0x00, 0x00,
- + 0x00, 0x0B, 0x94, 0xEB,
- + };
- +
- + #endif /* _RT2860_UCODE_H_ */
- +
- +
- *** /dev/null Mon Jun 6 17:35:57 2011
- --- rt2860_softc.h Mon Jun 6 17:39:05 2011
- ***************
- *** 0 ****
- --- 1,441 ----
- +
- + /*-
- + * Copyright (c) 2009-2010 Alexander Egorenkov <[email protected]>
- + * Copyright (c) 2009 Damien Bergamini <[email protected]>
- + * Bugs, incompatibilities etc added by Matt <[email protected]>
- + * 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 _RT2860_SOFTC_H_
- + #define _RT2860_SOFTC_H_
- +
- + #include <sys/param.h>
- + #include <sys/sysctl.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/taskqueue.h>
- + #include <sys/module.h>
- + #include <sys/bus.h>
- + #include <sys/endian.h>
- +
- + #include <machine/bus.h>
- + #include <machine/resource.h>
- + #include <sys/rman.h>
- +
- + #include <net/bpf.h>
- + #include <net/if.h>
- + #include <net/if_arp.h>
- + #include <net/ethernet.h>
- + #include <net/if_dl.h>
- + #include <net/if_media.h>
- + #include <net/if_types.h>
- +
- + #include <net80211/ieee80211_var.h>
- + #include <net80211/ieee80211_input.h>
- + #include <net80211/ieee80211_radiotap.h>
- + #include <net80211/ieee80211_regdomain.h>
- +
- + #include <dev/ral/rt2860_rxdesc.h>
- + #include <dev/ral/rt2860_txdesc.h>
- + #include <dev/ral/rt2860_txwi.h>
- + #include <dev/ral/rt2860_amrr.h>
- +
- + #define RT2860_SOFTC_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
- + #define RT2860_SOFTC_UNLOCK(sc) \
- + mtx_unlock(&(sc)->sc_mtx)
- + #define RT2860_SOFTC_ASSERT_LOCKED(sc) \
- + mtx_assert(&(sc)->sc_mtx, MA_OWNED)
- +
- + #define RT2860_SOFTC_TX_RING_LOCK(ring) mtx_lock(&(ring)->lock)
- + #define RT2860_SOFTC_TX_RING_UNLOCK(ring) \
- + mtx_unlock(&(ring)->lock)
- + #define RT2860_SOFTC_TX_RING_ASSERT_LOCKED(ring) \
- + mtx_assert(&(ring)->lock, MA_OWNED)
- +
- + #define RT2860_SOFTC_FLAGS_UCODE_LOADED (1 << 0)
- +
- + #define RT2860_SOFTC_LED_OFF_COUNT 3
- +
- + #define RT2860_SOFTC_RSSI_OFF_COUNT 3
- +
- + #define RT2860_SOFTC_LNA_GAIN_COUNT 4
- +
- + #define RT2860_SOFTC_TXPOW_COUNT 50
- +
- + #define RT2860_SOFTC_TXPOW_RATE_COUNT 5
- +
- + #define RT2860_SOFTC_TSSI_COUNT 9
- +
- + #define RT2860_SOFTC_BBP_EEPROM_COUNT 8
- +
- + #define RT2860_SOFTC_RSSI_COUNT 3
- +
- + #define RT2860_SOFTC_STAID_COUNT 64
- +
- + #define RT2860_SOFTC_TX_RING_COUNT 6
- +
- + #define RT2860_SOFTC_RX_RING_DATA_COUNT 128
- +
- + #define RT2860_SOFTC_MAX_SCATTER 10
- +
- + #define RT2860_SOFTC_TX_RING_DATA_COUNT 256
- + #define RT2860_SOFTC_TX_RING_DESC_COUNT \
- + (RT2860_SOFTC_TX_RING_DATA_COUNT * RT2860_SOFTC_MAX_SCATTER)
- +
- + #define RT2860_SOFTC_RX_RADIOTAP_PRESENT \
- + ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- + (1 << IEEE80211_RADIOTAP_RATE) | \
- + (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
- + (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
- + (1 << IEEE80211_RADIOTAP_ANTENNA) | \
- + (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
- + (1 << IEEE80211_RADIOTAP_XCHANNEL))
- +
- + #define RT2860_SOFTC_TX_RADIOTAP_PRESENT \
- + ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- + (1 << IEEE80211_RADIOTAP_RATE) | \
- + (1 << IEEE80211_RADIOTAP_XCHANNEL))
- +
- + struct rt2860_softc_rx_data
- + {
- + bus_dmamap_t dma_map;
- + struct mbuf *m;
- + };
- +
- + struct rt2860_softc_rx_ring
- + {
- + bus_dma_tag_t desc_dma_tag;
- + bus_dmamap_t desc_dma_map;
- + bus_addr_t desc_phys_addr;
- + struct rt2860_rxdesc *desc;
- + bus_dma_tag_t data_dma_tag;
- + bus_dmamap_t spare_dma_map;
- + struct rt2860_softc_rx_data data[RT2860_SOFTC_RX_RING_DATA_COUNT];
- + int cur;
- + };
- +
- + struct rt2860_softc_tx_data
- + {
- + bus_dmamap_t dma_map;
- + struct ieee80211_node *ni;
- + struct mbuf *m;
- + };
- +
- + struct rt2860_softc_tx_ring
- + {
- + struct mtx lock;
- + bus_dma_tag_t desc_dma_tag;
- + bus_dmamap_t desc_dma_map;
- + bus_addr_t desc_phys_addr;
- + struct rt2860_txdesc *desc;
- + int desc_queued;
- + int desc_cur;
- + int desc_next;
- + bus_dma_tag_t seg0_dma_tag;
- + bus_dmamap_t seg0_dma_map;
- + bus_addr_t seg0_phys_addr;
- + uint8_t *seg0;
- + bus_dma_tag_t data_dma_tag;
- + struct rt2860_softc_tx_data data[RT2860_SOFTC_TX_RING_DATA_COUNT];
- + int data_queued;
- + int data_cur;
- + int data_next;
- + int qid;
- + };
- +
- + struct rt2860_softc_node
- + {
- + struct ieee80211_node ni;
- +
- + uint8_t staid;
- +
- + uint8_t last_rssi[RT2860_SOFTC_RSSI_COUNT];
- + int8_t last_rssi_dbm[RT2860_SOFTC_RSSI_COUNT];
- + };
- +
- + struct rt2860_softc_vap
- + {
- + struct ieee80211vap vap;
- +
- + struct ieee80211_beacon_offsets beacon_offsets;
- + struct mbuf *beacon_mbuf;
- + struct rt2860_txwi beacon_txwi;
- +
- + struct rt2860_amrr amrr;
- +
- + int (*newstate)(struct ieee80211vap *vap,
- + enum ieee80211_state nstate, int arg);
- + };
- +
- + struct rt2860_softc_rx_radiotap_header
- + {
- + struct ieee80211_radiotap_header ihdr;
- + uint8_t flags;
- + uint8_t rate;
- + int8_t dbm_antsignal;
- + int8_t dbm_antnoise;
- + uint8_t antenna;
- + uint8_t antsignal;
- + uint8_t pad[2];
- + uint32_t chan_flags;
- + uint16_t chan_freq;
- + uint8_t chan_ieee;
- + int8_t chan_maxpow;
- + } __packed;
- +
- + struct rt2860_softc_tx_radiotap_header
- + {
- + struct ieee80211_radiotap_header ihdr;
- + uint8_t flags;
- + uint8_t rate;
- + uint8_t pad[2];
- + uint32_t chan_flags;
- + uint16_t chan_freq;
- + uint8_t chan_ieee;
- + int8_t chan_maxpow;
- + } __packed;
- +
- + struct rt2860_softc
- + {
- +
- + struct ifnet *sc_ifp;
- + device_t sc_dev;
- + bus_space_tag_t sc_st;
- + bus_space_handle_t sc_sh;
- +
- + struct mtx sc_mtx;
- +
- + struct callout watchdog_ch;
- + int sc_id;
- + int sc_tx_timer;
- + int sc_invalid;
- + int sc_debug;
- +
- +
- + uint32_t flags;
- + /*
- + int mem_rid;
- + struct resource *mem;
- +
- + int irq_rid;
- + struct resource *irq;
- + */
- + void *irqh;
- +
- + int if_flags;
- +
- + int nvaps;
- + int napvaps;
- + int nadhocvaps;
- + int nstavaps;
- + int nwdsvaps;
- +
- + void (*node_cleanup)(struct ieee80211_node *ni);
- +
- + int (*recv_action)(struct ieee80211_node *ni,
- + const struct ieee80211_frame *wh,
- + const uint8_t *frm, const uint8_t *efrm);
- +
- + int (*send_action)(struct ieee80211_node *ni,
- + int cat, int act, void *sa);
- +
- + int (*addba_response)(struct ieee80211_node *ni,
- + struct ieee80211_tx_ampdu *tap,
- + int status, int baparamset, int batimeout);
- +
- + void (*addba_stop)(struct ieee80211_node *ni,
- + struct ieee80211_tx_ampdu *tap);
- +
- + int (*ampdu_rx_start)(struct ieee80211_node *ni,
- + struct ieee80211_rx_ampdu *rap,
- + int baparamset, int batimeout, int baseqctl);
- +
- + void (*ampdu_rx_stop)(struct ieee80211_node *ni,
- + struct ieee80211_rx_ampdu *rap);
- +
- + struct rt2860_amrr_node amrr_node[RT2860_SOFTC_STAID_COUNT];
- +
- + uint32_t mac_rev;
- + uint8_t eeprom_addr_num;
- + uint16_t eeprom_rev;
- + uint8_t rf_rev;
- +
- + uint8_t mac_addr[IEEE80211_ADDR_LEN];
- +
- + uint8_t ntxpath;
- + uint8_t nrxpath;
- +
- + int hw_radio_cntl;
- + int tx_agc_cntl;
- + int ext_lna_2ghz;
- + int ext_lna_5ghz;
- +
- + uint8_t country_2ghz;
- + uint8_t country_5ghz;
- +
- + uint8_t rf_freq_off;
- +
- + uint8_t led_cntl;
- + uint16_t led_off[RT2860_SOFTC_LED_OFF_COUNT];
- +
- + int8_t rssi_off_2ghz[RT2860_SOFTC_RSSI_OFF_COUNT];
- + int8_t rssi_off_5ghz[RT2860_SOFTC_RSSI_OFF_COUNT];
- +
- + int8_t lna_gain[RT2860_SOFTC_LNA_GAIN_COUNT];
- +
- + int8_t txpow1[RT2860_SOFTC_TXPOW_COUNT];
- + int8_t txpow2[RT2860_SOFTC_TXPOW_COUNT];
- +
- + int8_t txpow_rate_delta_2ghz;
- + int8_t txpow_rate_delta_5ghz;
- + uint32_t txpow_rate_20mhz[RT2860_SOFTC_TXPOW_RATE_COUNT];
- + uint32_t txpow_rate_40mhz_2ghz[RT2860_SOFTC_TXPOW_RATE_COUNT];
- + uint32_t txpow_rate_40mhz_5ghz[RT2860_SOFTC_TXPOW_RATE_COUNT];
- +
- + int tx_agc_cntl_2ghz;
- + int tx_agc_cntl_5ghz;
- +
- + uint8_t tssi_2ghz[RT2860_SOFTC_TSSI_COUNT];
- + uint8_t tssi_step_2ghz;
- + uint8_t tssi_5ghz[RT2860_SOFTC_TSSI_COUNT];
- + uint8_t tssi_step_5ghz;
- +
- + struct
- + {
- + uint8_t val;
- + uint8_t reg;
- + } __packed bbp_eeprom[RT2860_SOFTC_BBP_EEPROM_COUNT], rf[10];
- +
- + uint16_t powersave_level;
- +
- + uint8_t staid_mask[RT2860_SOFTC_STAID_COUNT / NBBY];
- +
- + uint32_t intr_enable_mask;
- + uint32_t intr_disable_mask;
- + uint32_t intr_pending_mask;
- +
- + struct task rx_done_task;
- + int rx_process_limit;
- +
- + struct task tx_done_task;
- +
- + struct task fifo_sta_full_task;
- +
- + struct task periodic_task;
- + struct callout periodic_ch;
- + unsigned long periodic_round;
- +
- + struct taskqueue *taskqueue;
- +
- + struct rt2860_softc_rx_ring rx_ring;
- +
- + struct rt2860_softc_tx_ring tx_ring[RT2860_SOFTC_TX_RING_COUNT];
- + int tx_ring_mgtqid;
- +
- + struct callout tx_watchdog_ch;
- + int tx_timer;
- +
- + struct rt2860_softc_rx_radiotap_header rxtap;
- + struct rt2860_softc_tx_radiotap_header txtap;
- +
- + /* statistic counters */
- +
- + unsigned long interrupts;
- + unsigned long tx_coherent_interrupts;
- + unsigned long rx_coherent_interrupts;
- + unsigned long txrx_coherent_interrupts;
- + unsigned long fifo_sta_full_interrupts;
- + unsigned long rx_interrupts;
- + unsigned long rx_delay_interrupts;
- + unsigned long tx_interrupts[RT2860_SOFTC_TX_RING_COUNT];
- + unsigned long tx_delay_interrupts;
- + unsigned long pre_tbtt_interrupts;
- + unsigned long tbtt_interrupts;
- + unsigned long mcu_cmd_interrupts;
- + unsigned long auto_wakeup_interrupts;
- + unsigned long gp_timer_interrupts;
- +
- + unsigned long tx_data_queue_full[RT2860_SOFTC_TX_RING_COUNT];
- +
- + unsigned long tx_watchdog_timeouts;
- +
- + unsigned long tx_defrag_packets;
- +
- + unsigned long no_tx_desc_avail;
- +
- + unsigned long rx_mbuf_alloc_errors;
- + unsigned long rx_mbuf_dmamap_errors;
- +
- + unsigned long tx_queue_not_empty[2];
- +
- + unsigned long tx_beacons;
- + unsigned long tx_noretryok;
- + unsigned long tx_retryok;
- + unsigned long tx_failed;
- + unsigned long tx_underflows;
- + unsigned long tx_zerolen;
- + unsigned long tx_nonagg;
- + unsigned long tx_agg;
- + unsigned long tx_ampdu;
- + unsigned long tx_mpdu_zero_density;
- + unsigned long tx_ampdu_sessions;
- +
- + unsigned long rx_packets;
- + unsigned long rx_ampdu;
- + unsigned long rx_ampdu_retries;
- + unsigned long rx_mpdu_zero_density;
- + unsigned long rx_ampdu_sessions;
- + unsigned long rx_amsdu;
- + unsigned long rx_crc_errors;
- + unsigned long rx_phy_errors;
- + unsigned long rx_false_ccas;
- + unsigned long rx_plcp_errors;
- + unsigned long rx_dup_packets;
- + unsigned long rx_fifo_overflows;
- + unsigned long rx_cipher_no_errors;
- + unsigned long rx_cipher_icv_errors;
- + unsigned long rx_cipher_mic_errors;
- + unsigned long rx_cipher_invalid_key_errors;
- +
- + int tx_stbc;
- +
- + uint8_t rf24_20mhz;
- + uint8_t rf24_40mhz;
- + uint8_t patch_dac;
- + uint8_t txmixgain_2ghz;
- + uint8_t txmixgain_5ghz;
- +
- + #ifdef RT2860_DEBUG
- + int debug;
- + #endif
- + };
- +
- +
- + int rt2860_attach(device_t dev,int ignore);
- +
- + int rt2860_detach(void *xsc);
- +
- + void rt2860_shutdown(void *xsc);
- +
- + void rt2860_suspend(void *xsc);
- +
- + void rt2860_resume(void *xsc);
- +
- + void rt2860_intr(void *arg);
- +
- +
- + #endif /* #ifndef _RT2860_SOFTC_H_ */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement