[haiku-commits] r39080 - in haiku/vendor/freebsd/current/dev: . rt2860

  • From: coling@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 23 Oct 2010 22:03:37 +0200 (CEST)

Author: colin
Date: 2010-10-23 22:03:37 +0200 (Sat, 23 Oct 2010)
New Revision: 39080
Changeset: http://dev.haiku-os.org/changeset/39080

Added:
   haiku/vendor/freebsd/current/dev/rt2860/
   haiku/vendor/freebsd/current/dev/rt2860/Makefile
   haiku/vendor/freebsd/current/dev/rt2860/rt2860.c
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_amrr.c
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_amrr.h
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_debug.h
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_eeprom.h
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_io.c
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_io.h
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_led.c
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_led.h
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_read_eeprom.c
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_read_eeprom.h
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_reg.h
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_rf.c
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_rf.h
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_rxdesc.h
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_rxwi.h
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_softc.h
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_txdesc.h
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_txwi.h
   haiku/vendor/freebsd/current/dev/rt2860/rt2860_ucode.h
Log:
Importing Ralink 2860 driver from git-repository
http://repo.or.cz/w/ralink_drivers/rt2860_fbsd8.git using commit hash
c58bf9b6971dbfa96770ee2b8358a04e37536971.


Added: haiku/vendor/freebsd/current/dev/rt2860/Makefile
===================================================================
--- haiku/vendor/freebsd/current/dev/rt2860/Makefile                            
(rev 0)
+++ haiku/vendor/freebsd/current/dev/rt2860/Makefile    2010-10-23 20:03:37 UTC 
(rev 39080)
@@ -0,0 +1,18 @@
+
+SRCS =         device_if.h \
+               bus_if.h \
+               pci_if.h \
+               rt2860_io.c \
+               rt2860_read_eeprom.c \
+               rt2860_led.c \
+               rt2860_rf.c \
+               rt2860_amrr.c \
+               rt2860.c
+
+KMOD = rt2860
+
+DEBUG_FLAGS = -g
+WERROR =
+CFLAGS += -DRT2860_DEBUG
+
+.include <bsd.kmod.mk>

Added: haiku/vendor/freebsd/current/dev/rt2860/rt2860.c
===================================================================
--- haiku/vendor/freebsd/current/dev/rt2860/rt2860.c                            
(rev 0)
+++ haiku/vendor/freebsd/current/dev/rt2860/rt2860.c    2010-10-23 20:03:37 UTC 
(rev 39080)
@@ -0,0 +1,7182 @@
+
+/*-
+ * Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@xxxxxxxxx>
+ * Copyright (c) 2009 Damien Bergamini <damien.bergamini@xxxxxxx>
+ *
+ * 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 "rt2860_softc.h"
+#include "rt2860_reg.h"
+#include "rt2860_eeprom.h"
+#include "rt2860_ucode.h"
+#include "rt2860_txwi.h"
+#include "rt2860_rxwi.h"
+#include "rt2860_io.h"
+#include "rt2860_read_eeprom.h"
+#include "rt2860_led.h"
+#include "rt2860_rf.h"
+#include "rt2860_debug.h"
+
+/*
+ * Defines and macros
+ */
+
+#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 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
+
+/*
+ * Data structures and types
+ */
+
+struct rt2860_pci_ident
+{
+       uint16_t vendor;
+       uint16_t device;
+       const char *name;
+};
+
+/*
+ * Static function prototypes
+ */
+
+static int rt2860_probe(device_t dev);
+
+static int rt2860_attach(device_t dev);
+
+static int rt2860_detach(device_t dev);
+
+static int rt2860_shutdown(device_t dev);
+
+static int rt2860_suspend(device_t dev);
+
+static int rt2860_resume(device_t dev);
+
+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 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 variables
+ */
+
+static const struct rt2860_pci_ident rt2860_pci_ids[] =
+{
+       { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2860_PCI, "Ralink RT2860 PCI" 
},
+       { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2860_PCIe, "Ralink RT2860 
PCIe" },
+       { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2760_PCI, "Ralink RT2760 PCI" 
},
+       { PCI_VENDOR_RALINK, PCI_PRODUCT_RALINK_RT2790_PCIe, "Ralink RT2790 
PCIe" },
+       { 0, 0, NULL }
+};
+
+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.rt2860.tx_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.rt2860.debug", &rt2860_debug);
+#endif
+
+/*
+ * rt2860_probe
+ */
+static int rt2860_probe(device_t dev)
+{
+       const struct rt2860_pci_ident *ident;
+
+       for (ident = rt2860_pci_ids; ident->name != NULL; ident++)
+       {
+               if (pci_get_vendor(dev) == ident->vendor &&
+                       pci_get_device(dev) == ident->device)
+               {
+                       device_set_desc(dev, ident->name);
+                       return 0;
+               }
+       }
+
+       return ENXIO;
+}
+
+/*
+ * rt2860_attach
+ */
+static int rt2860_attach(device_t dev)
+{
+       struct rt2860_softc *sc;
+       struct ifnet *ifp;
+       struct ieee80211com *ic;
+       int error, ntries, i;
+
+       sc = device_get_softc(dev);
+
+       if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0)
+       {
+               printf("%s: chip is in D%d power mode, setting to D0\n",
+                       device_get_nameunit(dev), pci_get_powerstate(dev));
+               pci_set_powerstate(dev, PCI_POWERSTATE_D0);
+       }
+
+       /* enable bus-mastering */
+
+       pci_enable_busmaster(dev);
+
+       sc->dev = dev;
+
+       mtx_init(&sc->lock, device_get_nameunit(dev),
+               MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE);
+
+       sc->mem_rid = PCIR_BAR(0);
+       sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+               &sc->mem_rid, RF_ACTIVE);
+       if (sc->mem == NULL)
+       {
+               printf("%s: could not allocate memory resource\n",
+                       device_get_nameunit(dev));
+               error = ENXIO;
+               goto fail;
+       }
+
+       sc->bst = rman_get_bustag(sc->mem);
+       sc->bsh = 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: could not allocate interrupt 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->dev));
+
+       /* wait for NIC to initialize */
+
+       for (ntries = 0; ntries < 100; 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 == 100)
+       {
+               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->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->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->dev));
+               goto fail;
+       }
+
+       callout_init(&sc->periodic_ch, 0);
+       callout_init_mtx(&sc->tx_watchdog_ch, &sc->lock, 0);
+
+       ifp = sc->ifp = if_alloc(IFT_IEEE80211);
+       if (ifp == NULL)
+       {
+               printf("%s: could not if_alloc()\n",
+                       device_get_nameunit(sc->dev));
+               error = ENOMEM;
+               goto fail;
+       }
+
+       ifp->if_softc = sc;
+
+       if_initname(ifp, "rt2860", device_get_unit(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->dev));
+
+       rt2860_sysctl_attach(sc);
+
+       if (bootverbose)
+               ieee80211_announce(ic);
+
+       /* set up interrupt */
+
+       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->lock);
+
+       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
+ */
+static int rt2860_detach(device_t dev)
+{
+       struct rt2860_softc *sc;
+       struct ifnet *ifp;
+       struct ieee80211com *ic;
+       int i;
+
+       sc = device_get_softc(dev);
+       ifp = sc->ifp;
+       ic = ifp->if_l2com;
+
+       RT2860_DPRINTF(sc, RT2860_DEBUG_ANY,
+               "%s: detaching\n",
+               device_get_nameunit(sc->dev));
+
+       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->lock);
+
+       bus_generic_detach(dev);
+
+       bus_teardown_intr(dev, sc->irq, sc->irqh);
+
+       bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
+
+       bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
+
+       return 0;
+}
+
+/*
+ * rt2860_shutdown
+ */
+static int rt2860_shutdown(device_t dev)
+{
+       struct rt2860_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       RT2860_DPRINTF(sc, RT2860_DEBUG_ANY,
+               "%s: shutting down\n",
+               device_get_nameunit(sc->dev));
+
+       rt2860_stop(sc);
+
+       sc->flags &= ~RT2860_SOFTC_FLAGS_UCODE_LOADED;
+
+       return 0;
+}
+
+/*
+ * rt2860_suspend
+ */
+static int rt2860_suspend(device_t dev)
+{
+       struct rt2860_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       RT2860_DPRINTF(sc, RT2860_DEBUG_ANY,
+               "%s: suspending\n",
+               device_get_nameunit(sc->dev));
+
+       rt2860_stop(sc);
+
+       sc->flags &= ~RT2860_SOFTC_FLAGS_UCODE_LOADED;
+
+       return 0;
+}
+
+/*
+ * rt2860_resume
+ */
+static int rt2860_resume(device_t dev)
+{
+       struct rt2860_softc *sc;
+       struct ifnet *ifp;
+
+       sc = device_get_softc(dev);
+       ifp = sc->ifp;
+
+       RT2860_DPRINTF(sc, RT2860_DEBUG_ANY,
+               "%s: resuming\n",
+               device_get_nameunit(sc->dev));
+
+       if (ifp->if_flags & IFF_UP)
+               rt2860_init(sc);
+
+       return 0;
+}
+
+/*
+ * 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->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)
+       {
+               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)
+               {

[... truncated: 10075 lines follow ...]

Other related posts:

  • » [haiku-commits] r39080 - in haiku/vendor/freebsd/current/dev: . rt2860 - coling