110115c80Sfei feng - Sun Microsystems - Beijing China /*
2*0dc2366fSVenugopal Iyer * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
310115c80Sfei feng - Sun Microsystems - Beijing China * Use is subject to license terms.
410115c80Sfei feng - Sun Microsystems - Beijing China */
510115c80Sfei feng - Sun Microsystems - Beijing China
610115c80Sfei feng - Sun Microsystems - Beijing China /*
710115c80Sfei feng - Sun Microsystems - Beijing China * Copyright (c) 2006
810115c80Sfei feng - Sun Microsystems - Beijing China * Damien Bergamini <damien.bergamini@free.fr>
910115c80Sfei feng - Sun Microsystems - Beijing China *
1010115c80Sfei feng - Sun Microsystems - Beijing China * Permission to use, copy, modify, and distribute this software for any
1110115c80Sfei feng - Sun Microsystems - Beijing China * purpose with or without fee is hereby granted, provided that the above
1210115c80Sfei feng - Sun Microsystems - Beijing China * copyright notice and this permission notice appear in all copies.
1310115c80Sfei feng - Sun Microsystems - Beijing China *
1410115c80Sfei feng - Sun Microsystems - Beijing China * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1510115c80Sfei feng - Sun Microsystems - Beijing China * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1610115c80Sfei feng - Sun Microsystems - Beijing China * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1710115c80Sfei feng - Sun Microsystems - Beijing China * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1810115c80Sfei feng - Sun Microsystems - Beijing China * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1910115c80Sfei feng - Sun Microsystems - Beijing China * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2010115c80Sfei feng - Sun Microsystems - Beijing China * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2110115c80Sfei feng - Sun Microsystems - Beijing China */
2210115c80Sfei feng - Sun Microsystems - Beijing China
2310115c80Sfei feng - Sun Microsystems - Beijing China /*
2410115c80Sfei feng - Sun Microsystems - Beijing China * Ralink Technology RT2561, RT2561S and RT2661 chipset driver
2510115c80Sfei feng - Sun Microsystems - Beijing China * http://www.ralinktech.com/
2610115c80Sfei feng - Sun Microsystems - Beijing China */
2710115c80Sfei feng - Sun Microsystems - Beijing China
2810115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/types.h>
2910115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/byteorder.h>
3010115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/conf.h>
3110115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/cmn_err.h>
3210115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/stat.h>
3310115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/ddi.h>
3410115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/sunddi.h>
3510115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/strsubr.h>
3610115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/ethernet.h>
3710115c80Sfei feng - Sun Microsystems - Beijing China #include <inet/common.h>
3810115c80Sfei feng - Sun Microsystems - Beijing China #include <inet/nd.h>
3910115c80Sfei feng - Sun Microsystems - Beijing China #include <inet/mi.h>
4010115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/note.h>
4110115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/stream.h>
4210115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/strsun.h>
4310115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/modctl.h>
4410115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/devops.h>
4510115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/dlpi.h>
4610115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/mac_provider.h>
4710115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/mac_wifi.h>
4810115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/net80211.h>
4910115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/net80211_proto.h>
5010115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/varargs.h>
5110115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/policy.h>
5210115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/pci.h>
5310115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/crypto/common.h>
5410115c80Sfei feng - Sun Microsystems - Beijing China #include <sys/crypto/api.h>
5510115c80Sfei feng - Sun Microsystems - Beijing China #include <inet/wifi_ioctl.h>
5610115c80Sfei feng - Sun Microsystems - Beijing China
5710115c80Sfei feng - Sun Microsystems - Beijing China #include "rt2661_reg.h"
5810115c80Sfei feng - Sun Microsystems - Beijing China #include "rt2661_var.h"
5910115c80Sfei feng - Sun Microsystems - Beijing China #include "rt2661_ucode.h"
6010115c80Sfei feng - Sun Microsystems - Beijing China
6110115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_DBG_80211 (1 << 0)
6210115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_DBG_DMA (1 << 1)
6310115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_DBG_EEPROM (1 << 2)
6410115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_DBG_FW (1 << 3)
6510115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_DBG_HW (1 << 4)
6610115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_DBG_INTR (1 << 5)
6710115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_DBG_RX (1 << 6)
6810115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_DBG_SCAN (1 << 7)
6910115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_DBG_TX (1 << 8)
7010115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_DBG_RADIO (1 << 9)
7110115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_DBG_RESUME (1 << 10)
7210115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_DBG_MSG (1 << 11)
7310115c80Sfei feng - Sun Microsystems - Beijing China
7410115c80Sfei feng - Sun Microsystems - Beijing China uint32_t rt2661_dbg_flags = 0;
7510115c80Sfei feng - Sun Microsystems - Beijing China
7610115c80Sfei feng - Sun Microsystems - Beijing China #ifdef DEBUG
7710115c80Sfei feng - Sun Microsystems - Beijing China #define RWD_DEBUG \
7810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_debug
7910115c80Sfei feng - Sun Microsystems - Beijing China #else
8010115c80Sfei feng - Sun Microsystems - Beijing China #define RWD_DEBUG
8110115c80Sfei feng - Sun Microsystems - Beijing China #endif
8210115c80Sfei feng - Sun Microsystems - Beijing China
8310115c80Sfei feng - Sun Microsystems - Beijing China static void *rt2661_soft_state_p = NULL;
8410115c80Sfei feng - Sun Microsystems - Beijing China
8510115c80Sfei feng - Sun Microsystems - Beijing China static const uint8_t *ucode = NULL;
8610115c80Sfei feng - Sun Microsystems - Beijing China int usize;
8710115c80Sfei feng - Sun Microsystems - Beijing China
8810115c80Sfei feng - Sun Microsystems - Beijing China static const struct {
8910115c80Sfei feng - Sun Microsystems - Beijing China uint32_t reg;
9010115c80Sfei feng - Sun Microsystems - Beijing China uint32_t val;
9110115c80Sfei feng - Sun Microsystems - Beijing China } rt2661_def_mac[] = {
9210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_DEF_MAC
9310115c80Sfei feng - Sun Microsystems - Beijing China };
9410115c80Sfei feng - Sun Microsystems - Beijing China
9510115c80Sfei feng - Sun Microsystems - Beijing China static const struct {
9610115c80Sfei feng - Sun Microsystems - Beijing China uint8_t reg;
9710115c80Sfei feng - Sun Microsystems - Beijing China uint8_t val;
9810115c80Sfei feng - Sun Microsystems - Beijing China } rt2661_def_bbp[] = {
9910115c80Sfei feng - Sun Microsystems - Beijing China RT2661_DEF_BBP
10010115c80Sfei feng - Sun Microsystems - Beijing China };
10110115c80Sfei feng - Sun Microsystems - Beijing China
10210115c80Sfei feng - Sun Microsystems - Beijing China static const struct rfprog {
10310115c80Sfei feng - Sun Microsystems - Beijing China uint8_t chan;
10410115c80Sfei feng - Sun Microsystems - Beijing China uint32_t r1, r2, r3, r4;
10510115c80Sfei feng - Sun Microsystems - Beijing China } rt2661_rf5225_1[] = {
10610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_RF5225_1
10710115c80Sfei feng - Sun Microsystems - Beijing China }, rt2661_rf5225_2[] = {
10810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_RF5225_2
10910115c80Sfei feng - Sun Microsystems - Beijing China };
11010115c80Sfei feng - Sun Microsystems - Beijing China
11110115c80Sfei feng - Sun Microsystems - Beijing China /*
11210115c80Sfei feng - Sun Microsystems - Beijing China * PIO access attributes for registers
11310115c80Sfei feng - Sun Microsystems - Beijing China */
11410115c80Sfei feng - Sun Microsystems - Beijing China static ddi_device_acc_attr_t rt2661_csr_accattr = {
11510115c80Sfei feng - Sun Microsystems - Beijing China DDI_DEVICE_ATTR_V0,
11610115c80Sfei feng - Sun Microsystems - Beijing China DDI_STRUCTURE_LE_ACC,
11710115c80Sfei feng - Sun Microsystems - Beijing China DDI_STRICTORDER_ACC
11810115c80Sfei feng - Sun Microsystems - Beijing China };
11910115c80Sfei feng - Sun Microsystems - Beijing China
12010115c80Sfei feng - Sun Microsystems - Beijing China /*
12110115c80Sfei feng - Sun Microsystems - Beijing China * DMA access attributes for descriptors: NOT to be byte swapped.
12210115c80Sfei feng - Sun Microsystems - Beijing China */
12310115c80Sfei feng - Sun Microsystems - Beijing China static ddi_device_acc_attr_t rt2661_desc_accattr = {
12410115c80Sfei feng - Sun Microsystems - Beijing China DDI_DEVICE_ATTR_V0,
12510115c80Sfei feng - Sun Microsystems - Beijing China DDI_STRUCTURE_LE_ACC,
12610115c80Sfei feng - Sun Microsystems - Beijing China DDI_STRICTORDER_ACC
12710115c80Sfei feng - Sun Microsystems - Beijing China };
12810115c80Sfei feng - Sun Microsystems - Beijing China
12910115c80Sfei feng - Sun Microsystems - Beijing China static ddi_device_acc_attr_t rt2661_buf_accattr = {
13010115c80Sfei feng - Sun Microsystems - Beijing China DDI_DEVICE_ATTR_V0,
13110115c80Sfei feng - Sun Microsystems - Beijing China DDI_NEVERSWAP_ACC,
13210115c80Sfei feng - Sun Microsystems - Beijing China DDI_STRICTORDER_ACC,
13310115c80Sfei feng - Sun Microsystems - Beijing China DDI_DEFAULT_ACC
13410115c80Sfei feng - Sun Microsystems - Beijing China };
13510115c80Sfei feng - Sun Microsystems - Beijing China
13610115c80Sfei feng - Sun Microsystems - Beijing China /*
13710115c80Sfei feng - Sun Microsystems - Beijing China * Describes the chip's DMA engine
13810115c80Sfei feng - Sun Microsystems - Beijing China */
13910115c80Sfei feng - Sun Microsystems - Beijing China static ddi_dma_attr_t rt2661_dma_attr = {
14010115c80Sfei feng - Sun Microsystems - Beijing China DMA_ATTR_V0, /* dma_attr version */
14110115c80Sfei feng - Sun Microsystems - Beijing China 0x0, /* dma_attr_addr_lo */
14210115c80Sfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* dma_attr_addr_hi */
14310115c80Sfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* dma_attr_count_max */
14410115c80Sfei feng - Sun Microsystems - Beijing China 1, /* dma_attr_align */
14510115c80Sfei feng - Sun Microsystems - Beijing China 0x00000fff, /* dma_attr_burstsizes */
14610115c80Sfei feng - Sun Microsystems - Beijing China 1, /* dma_attr_minxfer */
14710115c80Sfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* dma_attr_maxxfer */
14810115c80Sfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* dma_attr_seg */
14910115c80Sfei feng - Sun Microsystems - Beijing China 1, /* dma_attr_sgllen */
15010115c80Sfei feng - Sun Microsystems - Beijing China 1, /* dma_attr_granular */
15110115c80Sfei feng - Sun Microsystems - Beijing China 0 /* dma_attr_flags */
15210115c80Sfei feng - Sun Microsystems - Beijing China };
15310115c80Sfei feng - Sun Microsystems - Beijing China
15410115c80Sfei feng - Sun Microsystems - Beijing China static const struct ieee80211_rateset rt2661_rateset_11b =
15510115c80Sfei feng - Sun Microsystems - Beijing China { 4, { 2, 4, 11, 22 } };
15610115c80Sfei feng - Sun Microsystems - Beijing China
15710115c80Sfei feng - Sun Microsystems - Beijing China static const struct ieee80211_rateset rt2661_rateset_11g =
15810115c80Sfei feng - Sun Microsystems - Beijing China { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
15910115c80Sfei feng - Sun Microsystems - Beijing China
16010115c80Sfei feng - Sun Microsystems - Beijing China
16110115c80Sfei feng - Sun Microsystems - Beijing China static const char *rt2661_get_rf(int);
16210115c80Sfei feng - Sun Microsystems - Beijing China
16310115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_read_eeprom(struct rt2661_softc *);
16410115c80Sfei feng - Sun Microsystems - Beijing China static uint16_t rt2661_eeprom_read(struct rt2661_softc *, uint8_t);
16510115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_load_microcode(struct rt2661_softc *,
16610115c80Sfei feng - Sun Microsystems - Beijing China const uint8_t *, int);
16710115c80Sfei feng - Sun Microsystems - Beijing China
16810115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_alloc_dma_mem(dev_info_t *, ddi_dma_attr_t *, size_t,
16910115c80Sfei feng - Sun Microsystems - Beijing China ddi_device_acc_attr_t *, uint_t, uint_t, struct dma_area *);
17010115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_free_dma_mem(struct dma_area *);
17110115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_alloc_tx_ring(struct rt2661_softc *,
17210115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_ring *, int);
17310115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_reset_tx_ring(struct rt2661_softc *,
17410115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_ring *);
17510115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_free_tx_ring(struct rt2661_softc *,
17610115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_ring *);
17710115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_alloc_rx_ring(struct rt2661_softc *,
17810115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_rx_ring *, int);
17910115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_reset_rx_ring(struct rt2661_softc *,
18010115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_rx_ring *);
18110115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_free_rx_ring(struct rt2661_softc *,
18210115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_rx_ring *);
18310115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_tx_dma_intr(struct rt2661_softc *,
18410115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_ring *);
18510115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_tx_intr(struct rt2661_softc *);
18610115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_rx_intr(struct rt2661_softc *);
18710115c80Sfei feng - Sun Microsystems - Beijing China static uint_t rt2661_softintr(caddr_t, caddr_t);
18810115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_mcu_wakeup(struct rt2661_softc *);
18910115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_mcu_cmd_intr(struct rt2661_softc *);
19010115c80Sfei feng - Sun Microsystems - Beijing China static uint_t rt2661_intr(caddr_t, caddr_t);
19110115c80Sfei feng - Sun Microsystems - Beijing China
19210115c80Sfei feng - Sun Microsystems - Beijing China static uint16_t rt2661_txtime(int, int, uint32_t);
19310115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_ack_rate(struct ieee80211com *, int);
19410115c80Sfei feng - Sun Microsystems - Beijing China static uint8_t rt2661_plcp_signal(int);
19510115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_setup_tx_desc(struct rt2661_softc *,
19610115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_desc *, uint32_t, uint16_t, int,
19710115c80Sfei feng - Sun Microsystems - Beijing China int, int);
19810115c80Sfei feng - Sun Microsystems - Beijing China
19910115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_get_rssi(struct rt2661_softc *, uint8_t);
20010115c80Sfei feng - Sun Microsystems - Beijing China
20110115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_send(ieee80211com_t *, mblk_t *);
20210115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_mgmt_send(ieee80211com_t *, mblk_t *, uint8_t);
20310115c80Sfei feng - Sun Microsystems - Beijing China
20410115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_amrr_node_init(const struct rt2661_amrr *,
20510115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_amrr_node *);
20610115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_amrr_choose(struct rt2661_amrr *,
20710115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *, struct rt2661_amrr_node *);
20810115c80Sfei feng - Sun Microsystems - Beijing China
20910115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_update_promisc(struct rt2661_softc *);
21010115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_updateslot(struct ieee80211com *, int);
21110115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_set_slottime(struct rt2661_softc *);
21210115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_enable_mrr(struct rt2661_softc *);
21310115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_set_txpreamble(struct rt2661_softc *);
21410115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_set_basicrates(struct rt2661_softc *);
21510115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_set_bssid(struct rt2661_softc *, const uint8_t *);
21610115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_newassoc(struct ieee80211com *, struct ieee80211_node *);
21710115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_updatestats(void *);
21810115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_rx_tune(struct rt2661_softc *);
21910115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_enable_tsf_sync(struct rt2661_softc *);
22010115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_newstate(struct ieee80211com *,
22110115c80Sfei feng - Sun Microsystems - Beijing China enum ieee80211_state, int);
22210115c80Sfei feng - Sun Microsystems - Beijing China
22310115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_set_macaddr(struct rt2661_softc *, const uint8_t *);
22410115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_bbp_init(struct rt2661_softc *);
22510115c80Sfei feng - Sun Microsystems - Beijing China static uint8_t rt2661_bbp_read(struct rt2661_softc *, uint8_t);
22610115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_bbp_write(struct rt2661_softc *, uint8_t, uint8_t);
22710115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_select_band(struct rt2661_softc *,
22810115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211_channel *);
22910115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_select_antenna(struct rt2661_softc *);
23010115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_rf_write(struct rt2661_softc *, uint8_t, uint32_t);
23110115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_set_chan(struct rt2661_softc *,
23210115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211_channel *);
23310115c80Sfei feng - Sun Microsystems - Beijing China
23410115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_stop_locked(struct rt2661_softc *);
23510115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_init(struct rt2661_softc *);
23610115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_stop(struct rt2661_softc *);
23710115c80Sfei feng - Sun Microsystems - Beijing China /*
23810115c80Sfei feng - Sun Microsystems - Beijing China * device operations
23910115c80Sfei feng - Sun Microsystems - Beijing China */
24010115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_attach(dev_info_t *, ddi_attach_cmd_t);
24110115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_detach(dev_info_t *, ddi_detach_cmd_t);
24210115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_quiesce(dev_info_t *);
24310115c80Sfei feng - Sun Microsystems - Beijing China
24410115c80Sfei feng - Sun Microsystems - Beijing China /*
24510115c80Sfei feng - Sun Microsystems - Beijing China * Module Loading Data & Entry Points
24610115c80Sfei feng - Sun Microsystems - Beijing China */
24710115c80Sfei feng - Sun Microsystems - Beijing China DDI_DEFINE_STREAM_OPS(rwd_dev_ops, nulldev, nulldev, rt2661_attach,
24810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_detach, nodev, NULL, D_MP, NULL, rt2661_quiesce);
24910115c80Sfei feng - Sun Microsystems - Beijing China
25010115c80Sfei feng - Sun Microsystems - Beijing China static struct modldrv rwd_modldrv = {
25110115c80Sfei feng - Sun Microsystems - Beijing China &mod_driverops, /* Type of module. This one is a driver */
25210115c80Sfei feng - Sun Microsystems - Beijing China "Ralink RT2661 driver v1.1", /* short description */
25310115c80Sfei feng - Sun Microsystems - Beijing China &rwd_dev_ops /* driver specific ops */
25410115c80Sfei feng - Sun Microsystems - Beijing China };
25510115c80Sfei feng - Sun Microsystems - Beijing China
25610115c80Sfei feng - Sun Microsystems - Beijing China static struct modlinkage modlinkage = {
25710115c80Sfei feng - Sun Microsystems - Beijing China MODREV_1,
25810115c80Sfei feng - Sun Microsystems - Beijing China (void *)&rwd_modldrv,
25910115c80Sfei feng - Sun Microsystems - Beijing China NULL
26010115c80Sfei feng - Sun Microsystems - Beijing China };
26110115c80Sfei feng - Sun Microsystems - Beijing China
26210115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_m_stat(void *, uint_t, uint64_t *);
26310115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_m_start(void *);
26410115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_m_stop(void *);
26510115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_m_promisc(void *, boolean_t);
26610115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_m_multicst(void *, boolean_t, const uint8_t *);
26710115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_m_unicst(void *, const uint8_t *);
26810115c80Sfei feng - Sun Microsystems - Beijing China static mblk_t *rt2661_m_tx(void *, mblk_t *);
26910115c80Sfei feng - Sun Microsystems - Beijing China static void rt2661_m_ioctl(void *, queue_t *, mblk_t *);
27010115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_m_setprop(void *arg, const char *pr_name,
27110115c80Sfei feng - Sun Microsystems - Beijing China mac_prop_id_t wldp_pr_num,
27210115c80Sfei feng - Sun Microsystems - Beijing China uint_t wldp_length, const void *wldp_buf);
27310115c80Sfei feng - Sun Microsystems - Beijing China static int rt2661_m_getprop(void *arg, const char *pr_name,
274*0dc2366fSVenugopal Iyer mac_prop_id_t wldp_pr_num, uint_t wldp_length,
275*0dc2366fSVenugopal Iyer void *wldp_buf);
276*0dc2366fSVenugopal Iyer static void rt2661_m_propinfo(void *arg, const char *pr_name,
277*0dc2366fSVenugopal Iyer mac_prop_id_t wldp_pr_num, mac_prop_info_handle_t mph);
27810115c80Sfei feng - Sun Microsystems - Beijing China
27910115c80Sfei feng - Sun Microsystems - Beijing China static mac_callbacks_t rt2661_m_callbacks = {
280*0dc2366fSVenugopal Iyer MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO,
28110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_stat,
28210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_start,
28310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_stop,
28410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_promisc,
28510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_multicst,
28610115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_unicst,
28710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_tx,
288*0dc2366fSVenugopal Iyer NULL,
28910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_ioctl,
29010115c80Sfei feng - Sun Microsystems - Beijing China NULL,
29110115c80Sfei feng - Sun Microsystems - Beijing China NULL,
29210115c80Sfei feng - Sun Microsystems - Beijing China NULL,
29310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_setprop,
294*0dc2366fSVenugopal Iyer rt2661_m_getprop,
295*0dc2366fSVenugopal Iyer rt2661_m_propinfo
29610115c80Sfei feng - Sun Microsystems - Beijing China };
29710115c80Sfei feng - Sun Microsystems - Beijing China
29810115c80Sfei feng - Sun Microsystems - Beijing China #ifdef DEBUG
29910115c80Sfei feng - Sun Microsystems - Beijing China void
rt2661_debug(uint32_t dbg_flags,const int8_t * fmt,...)30010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_debug(uint32_t dbg_flags, const int8_t *fmt, ...)
30110115c80Sfei feng - Sun Microsystems - Beijing China {
30210115c80Sfei feng - Sun Microsystems - Beijing China va_list args;
30310115c80Sfei feng - Sun Microsystems - Beijing China
30410115c80Sfei feng - Sun Microsystems - Beijing China if (dbg_flags & rt2661_dbg_flags) {
30510115c80Sfei feng - Sun Microsystems - Beijing China va_start(args, fmt);
30610115c80Sfei feng - Sun Microsystems - Beijing China vcmn_err(CE_CONT, fmt, args);
30710115c80Sfei feng - Sun Microsystems - Beijing China va_end(args);
30810115c80Sfei feng - Sun Microsystems - Beijing China }
30910115c80Sfei feng - Sun Microsystems - Beijing China }
31010115c80Sfei feng - Sun Microsystems - Beijing China #endif
31110115c80Sfei feng - Sun Microsystems - Beijing China
31210115c80Sfei feng - Sun Microsystems - Beijing China /*
31310115c80Sfei feng - Sun Microsystems - Beijing China * Read 16 bits at address 'addr' from the serial EEPROM (either 93C46 or
31410115c80Sfei feng - Sun Microsystems - Beijing China * 93C66).
31510115c80Sfei feng - Sun Microsystems - Beijing China */
31610115c80Sfei feng - Sun Microsystems - Beijing China static uint16_t
rt2661_eeprom_read(struct rt2661_softc * sc,uint8_t addr)31710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_eeprom_read(struct rt2661_softc *sc, uint8_t addr)
31810115c80Sfei feng - Sun Microsystems - Beijing China {
31910115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
32010115c80Sfei feng - Sun Microsystems - Beijing China uint16_t val;
32110115c80Sfei feng - Sun Microsystems - Beijing China int n;
32210115c80Sfei feng - Sun Microsystems - Beijing China
32310115c80Sfei feng - Sun Microsystems - Beijing China /* clock C once before the first command */
32410115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, 0);
32510115c80Sfei feng - Sun Microsystems - Beijing China
32610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S);
32710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
32810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S);
32910115c80Sfei feng - Sun Microsystems - Beijing China
33010115c80Sfei feng - Sun Microsystems - Beijing China /* write start bit (1) */
33110115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D);
33210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D | RT2661_C);
33310115c80Sfei feng - Sun Microsystems - Beijing China
33410115c80Sfei feng - Sun Microsystems - Beijing China /* write READ opcode (10) */
33510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D);
33610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D | RT2661_C);
33710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S);
33810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
33910115c80Sfei feng - Sun Microsystems - Beijing China
34010115c80Sfei feng - Sun Microsystems - Beijing China /* write address (A5-A0 or A7-A0) */
34110115c80Sfei feng - Sun Microsystems - Beijing China n = (RT2661_READ(sc, RT2661_E2PROM_CSR) & RT2661_93C46) ? 5 : 7;
34210115c80Sfei feng - Sun Microsystems - Beijing China for (; n >= 0; n--) {
34310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S |
34410115c80Sfei feng - Sun Microsystems - Beijing China (((addr >> n) & 1) << RT2661_SHIFT_D));
34510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S |
34610115c80Sfei feng - Sun Microsystems - Beijing China (((addr >> n) & 1) << RT2661_SHIFT_D) | RT2661_C);
34710115c80Sfei feng - Sun Microsystems - Beijing China }
34810115c80Sfei feng - Sun Microsystems - Beijing China
34910115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S);
35010115c80Sfei feng - Sun Microsystems - Beijing China
35110115c80Sfei feng - Sun Microsystems - Beijing China /* read data Q15-Q0 */
35210115c80Sfei feng - Sun Microsystems - Beijing China val = 0;
35310115c80Sfei feng - Sun Microsystems - Beijing China for (n = 15; n >= 0; n--) {
35410115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
35510115c80Sfei feng - Sun Microsystems - Beijing China tmp = RT2661_READ(sc, RT2661_E2PROM_CSR);
35610115c80Sfei feng - Sun Microsystems - Beijing China val |= ((tmp & RT2661_Q) >> RT2661_SHIFT_Q) << n;
35710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S);
35810115c80Sfei feng - Sun Microsystems - Beijing China }
35910115c80Sfei feng - Sun Microsystems - Beijing China
36010115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, 0);
36110115c80Sfei feng - Sun Microsystems - Beijing China
36210115c80Sfei feng - Sun Microsystems - Beijing China /* clear Chip Select and clock C */
36310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_S);
36410115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, 0);
36510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_EEPROM_CTL(sc, RT2661_C);
36610115c80Sfei feng - Sun Microsystems - Beijing China
36710115c80Sfei feng - Sun Microsystems - Beijing China return (val);
36810115c80Sfei feng - Sun Microsystems - Beijing China }
36910115c80Sfei feng - Sun Microsystems - Beijing China
37010115c80Sfei feng - Sun Microsystems - Beijing China
37110115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_read_eeprom(struct rt2661_softc * sc)37210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_read_eeprom(struct rt2661_softc *sc)
37310115c80Sfei feng - Sun Microsystems - Beijing China {
37410115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
37510115c80Sfei feng - Sun Microsystems - Beijing China uint16_t val;
37610115c80Sfei feng - Sun Microsystems - Beijing China int i;
37710115c80Sfei feng - Sun Microsystems - Beijing China
37810115c80Sfei feng - Sun Microsystems - Beijing China /* read MAC address */
37910115c80Sfei feng - Sun Microsystems - Beijing China val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC01);
38010115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[0] = val & 0xff;
38110115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[1] = val >> 8;
38210115c80Sfei feng - Sun Microsystems - Beijing China
38310115c80Sfei feng - Sun Microsystems - Beijing China val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC23);
38410115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[2] = val & 0xff;
38510115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[3] = val >> 8;
38610115c80Sfei feng - Sun Microsystems - Beijing China
38710115c80Sfei feng - Sun Microsystems - Beijing China val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC45);
38810115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[4] = val & 0xff;
38910115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[5] = val >> 8;
39010115c80Sfei feng - Sun Microsystems - Beijing China
39110115c80Sfei feng - Sun Microsystems - Beijing China val = rt2661_eeprom_read(sc, RT2661_EEPROM_ANTENNA);
39210115c80Sfei feng - Sun Microsystems - Beijing China /* XXX: test if different from 0xffff? */
39310115c80Sfei feng - Sun Microsystems - Beijing China sc->rf_rev = (val >> 11) & 0x1f;
39410115c80Sfei feng - Sun Microsystems - Beijing China sc->hw_radio = (val >> 10) & 0x1;
39510115c80Sfei feng - Sun Microsystems - Beijing China sc->rx_ant = (val >> 4) & 0x3;
39610115c80Sfei feng - Sun Microsystems - Beijing China sc->tx_ant = (val >> 2) & 0x3;
39710115c80Sfei feng - Sun Microsystems - Beijing China sc->nb_ant = val & 0x3;
39810115c80Sfei feng - Sun Microsystems - Beijing China
39910115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
40010115c80Sfei feng - Sun Microsystems - Beijing China "RF revision=%d\n", sc->rf_rev);
40110115c80Sfei feng - Sun Microsystems - Beijing China
40210115c80Sfei feng - Sun Microsystems - Beijing China val = rt2661_eeprom_read(sc, RT2661_EEPROM_CONFIG2);
40310115c80Sfei feng - Sun Microsystems - Beijing China sc->ext_5ghz_lna = (val >> 6) & 0x1;
40410115c80Sfei feng - Sun Microsystems - Beijing China sc->ext_2ghz_lna = (val >> 4) & 0x1;
40510115c80Sfei feng - Sun Microsystems - Beijing China
40610115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
40710115c80Sfei feng - Sun Microsystems - Beijing China "External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
40810115c80Sfei feng - Sun Microsystems - Beijing China sc->ext_2ghz_lna, sc->ext_5ghz_lna);
40910115c80Sfei feng - Sun Microsystems - Beijing China
41010115c80Sfei feng - Sun Microsystems - Beijing China val = rt2661_eeprom_read(sc, RT2661_EEPROM_RSSI_2GHZ_OFFSET);
41110115c80Sfei feng - Sun Microsystems - Beijing China if ((val & 0xff) != 0xff)
41210115c80Sfei feng - Sun Microsystems - Beijing China sc->rssi_2ghz_corr = (int8_t)(val & 0xff);
41310115c80Sfei feng - Sun Microsystems - Beijing China
41410115c80Sfei feng - Sun Microsystems - Beijing China val = rt2661_eeprom_read(sc, RT2661_EEPROM_RSSI_5GHZ_OFFSET);
41510115c80Sfei feng - Sun Microsystems - Beijing China if ((val & 0xff) != 0xff)
41610115c80Sfei feng - Sun Microsystems - Beijing China sc->rssi_5ghz_corr = (int8_t)(val & 0xff);
41710115c80Sfei feng - Sun Microsystems - Beijing China
41810115c80Sfei feng - Sun Microsystems - Beijing China /* adjust RSSI correction for external low-noise amplifier */
41910115c80Sfei feng - Sun Microsystems - Beijing China if (sc->ext_2ghz_lna)
42010115c80Sfei feng - Sun Microsystems - Beijing China sc->rssi_2ghz_corr -= 14;
42110115c80Sfei feng - Sun Microsystems - Beijing China if (sc->ext_5ghz_lna)
42210115c80Sfei feng - Sun Microsystems - Beijing China sc->rssi_5ghz_corr -= 14;
42310115c80Sfei feng - Sun Microsystems - Beijing China
42410115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
42510115c80Sfei feng - Sun Microsystems - Beijing China "RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
42610115c80Sfei feng - Sun Microsystems - Beijing China sc->rssi_2ghz_corr, sc->rssi_5ghz_corr);
42710115c80Sfei feng - Sun Microsystems - Beijing China
42810115c80Sfei feng - Sun Microsystems - Beijing China val = rt2661_eeprom_read(sc, RT2661_EEPROM_FREQ_OFFSET);
42910115c80Sfei feng - Sun Microsystems - Beijing China if ((val >> 8) != 0xff)
43010115c80Sfei feng - Sun Microsystems - Beijing China sc->rfprog = (val >> 8) & 0x3;
43110115c80Sfei feng - Sun Microsystems - Beijing China if ((val & 0xff) != 0xff)
43210115c80Sfei feng - Sun Microsystems - Beijing China sc->rffreq = val & 0xff;
43310115c80Sfei feng - Sun Microsystems - Beijing China
43410115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
43510115c80Sfei feng - Sun Microsystems - Beijing China "RF prog=%d\nRF freq=%d\n", sc->rfprog, sc->rffreq);
43610115c80Sfei feng - Sun Microsystems - Beijing China
43710115c80Sfei feng - Sun Microsystems - Beijing China /* read Tx power for all a/b/g channels */
43810115c80Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < 19; i++) {
43910115c80Sfei feng - Sun Microsystems - Beijing China val = rt2661_eeprom_read(sc, RT2661_EEPROM_TXPOWER + i);
44010115c80Sfei feng - Sun Microsystems - Beijing China sc->txpow[i * 2] = (int8_t)(val >> 8);
44110115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
44210115c80Sfei feng - Sun Microsystems - Beijing China "Channel=%d Tx power=%d\n",
44310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf5225_1[i * 2].chan, sc->txpow[i * 2]);
44410115c80Sfei feng - Sun Microsystems - Beijing China sc->txpow[i * 2 + 1] = (int8_t)(val & 0xff);
44510115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
44610115c80Sfei feng - Sun Microsystems - Beijing China "Channel=%d Tx power=%d\n",
44710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf5225_1[i * 2 + 1].chan, sc->txpow[i * 2 + 1]);
44810115c80Sfei feng - Sun Microsystems - Beijing China }
44910115c80Sfei feng - Sun Microsystems - Beijing China
45010115c80Sfei feng - Sun Microsystems - Beijing China /* read vendor-specific BBP values */
45110115c80Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < 16; i++) {
45210115c80Sfei feng - Sun Microsystems - Beijing China val = rt2661_eeprom_read(sc, RT2661_EEPROM_BBP_BASE + i);
45310115c80Sfei feng - Sun Microsystems - Beijing China if (val == 0 || val == 0xffff)
45410115c80Sfei feng - Sun Microsystems - Beijing China continue;
45510115c80Sfei feng - Sun Microsystems - Beijing China sc->bbp_prom[i].reg = val >> 8;
45610115c80Sfei feng - Sun Microsystems - Beijing China sc->bbp_prom[i].val = val & 0xff;
45710115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
45810115c80Sfei feng - Sun Microsystems - Beijing China "BBP R%d=%02x\n", sc->bbp_prom[i].reg,
45910115c80Sfei feng - Sun Microsystems - Beijing China sc->bbp_prom[i].val);
46010115c80Sfei feng - Sun Microsystems - Beijing China }
46110115c80Sfei feng - Sun Microsystems - Beijing China }
46210115c80Sfei feng - Sun Microsystems - Beijing China
46310115c80Sfei feng - Sun Microsystems - Beijing China static const char *
rt2661_get_rf(int rev)46410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_get_rf(int rev)
46510115c80Sfei feng - Sun Microsystems - Beijing China {
46610115c80Sfei feng - Sun Microsystems - Beijing China switch (rev) {
46710115c80Sfei feng - Sun Microsystems - Beijing China case RT2661_RF_5225: return "RT5225";
46810115c80Sfei feng - Sun Microsystems - Beijing China case RT2661_RF_5325: return "RT5325 (MIMO XR)";
46910115c80Sfei feng - Sun Microsystems - Beijing China case RT2661_RF_2527: return "RT2527";
47010115c80Sfei feng - Sun Microsystems - Beijing China case RT2661_RF_2529: return "RT2529 (MIMO XR)";
47110115c80Sfei feng - Sun Microsystems - Beijing China default: return "unknown";
47210115c80Sfei feng - Sun Microsystems - Beijing China }
47310115c80Sfei feng - Sun Microsystems - Beijing China }
47410115c80Sfei feng - Sun Microsystems - Beijing China
47510115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_load_microcode(struct rt2661_softc * sc,const uint8_t * ucode_p,int size)47610115c80Sfei feng - Sun Microsystems - Beijing China rt2661_load_microcode(struct rt2661_softc *sc, const uint8_t *ucode_p, int size)
47710115c80Sfei feng - Sun Microsystems - Beijing China {
47810115c80Sfei feng - Sun Microsystems - Beijing China int ntries;
47910115c80Sfei feng - Sun Microsystems - Beijing China uint32_t off, i;
48010115c80Sfei feng - Sun Microsystems - Beijing China const uint8_t *fptr;
48110115c80Sfei feng - Sun Microsystems - Beijing China
48210115c80Sfei feng - Sun Microsystems - Beijing China fptr = ucode_p;
48310115c80Sfei feng - Sun Microsystems - Beijing China off = RT2661_MCU_CODE_BASE;
48410115c80Sfei feng - Sun Microsystems - Beijing China
48510115c80Sfei feng - Sun Microsystems - Beijing China /* reset 8051 */
48610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET);
48710115c80Sfei feng - Sun Microsystems - Beijing China
48810115c80Sfei feng - Sun Microsystems - Beijing China /* cancel any pending Host to MCU command */
48910115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_H2M_MAILBOX_CSR, 0);
49010115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_M2H_CMD_DONE_CSR, 0xffffffff);
49110115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_HOST_CMD_CSR, 0);
49210115c80Sfei feng - Sun Microsystems - Beijing China
49310115c80Sfei feng - Sun Microsystems - Beijing China /* write 8051's microcode */
49410115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR,
49510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_MCU_RESET | RT2661_MCU_SEL);
49610115c80Sfei feng - Sun Microsystems - Beijing China /* RT2661_WRITE_REGION_1(sc, RT2661_MCU_CODE_BASE, ucode, size); */
49710115c80Sfei feng - Sun Microsystems - Beijing China
49810115c80Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < size; i++) {
49910115c80Sfei feng - Sun Microsystems - Beijing China RT2661_MEM_WRITE1(sc, off++, *fptr++);
50010115c80Sfei feng - Sun Microsystems - Beijing China }
50110115c80Sfei feng - Sun Microsystems - Beijing China
50210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET);
50310115c80Sfei feng - Sun Microsystems - Beijing China
50410115c80Sfei feng - Sun Microsystems - Beijing China /* kick 8051's ass */
50510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR, 0);
50610115c80Sfei feng - Sun Microsystems - Beijing China
50710115c80Sfei feng - Sun Microsystems - Beijing China /* wait for 8051 to initialize */
50810115c80Sfei feng - Sun Microsystems - Beijing China for (ntries = 0; ntries < 500; ntries++) {
50910115c80Sfei feng - Sun Microsystems - Beijing China if (RT2661_READ(sc, RT2661_MCU_CNTL_CSR) & RT2661_MCU_READY)
51010115c80Sfei feng - Sun Microsystems - Beijing China break;
51110115c80Sfei feng - Sun Microsystems - Beijing China DELAY(100);
51210115c80Sfei feng - Sun Microsystems - Beijing China }
51310115c80Sfei feng - Sun Microsystems - Beijing China if (ntries == 500) {
51410115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_load_microcode(): "
51510115c80Sfei feng - Sun Microsystems - Beijing China "timeout waiting for MCU to initialize\n");
51610115c80Sfei feng - Sun Microsystems - Beijing China return (RT2661_FAILURE);
51710115c80Sfei feng - Sun Microsystems - Beijing China }
51810115c80Sfei feng - Sun Microsystems - Beijing China
51910115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_load_microcode(): "
52010115c80Sfei feng - Sun Microsystems - Beijing China "MCU initialized successfully\n");
52110115c80Sfei feng - Sun Microsystems - Beijing China return (RT2661_SUCCESS);
52210115c80Sfei feng - Sun Microsystems - Beijing China }
52310115c80Sfei feng - Sun Microsystems - Beijing China
52410115c80Sfei feng - Sun Microsystems - Beijing China /*
52510115c80Sfei feng - Sun Microsystems - Beijing China * Allocate an DMA memory and a DMA handle for accessing it
52610115c80Sfei feng - Sun Microsystems - Beijing China */
52710115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_alloc_dma_mem(dev_info_t * devinfo,ddi_dma_attr_t * dma_attr,size_t memsize,ddi_device_acc_attr_t * attr_p,uint_t alloc_flags,uint_t bind_flags,struct dma_area * dma_p)52810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_alloc_dma_mem(dev_info_t *devinfo, ddi_dma_attr_t *dma_attr,
52910115c80Sfei feng - Sun Microsystems - Beijing China size_t memsize, ddi_device_acc_attr_t *attr_p, uint_t alloc_flags,
53010115c80Sfei feng - Sun Microsystems - Beijing China uint_t bind_flags, struct dma_area *dma_p)
53110115c80Sfei feng - Sun Microsystems - Beijing China {
53210115c80Sfei feng - Sun Microsystems - Beijing China int err;
53310115c80Sfei feng - Sun Microsystems - Beijing China
53410115c80Sfei feng - Sun Microsystems - Beijing China /*
53510115c80Sfei feng - Sun Microsystems - Beijing China * Allocate handle
53610115c80Sfei feng - Sun Microsystems - Beijing China */
53710115c80Sfei feng - Sun Microsystems - Beijing China err = ddi_dma_alloc_handle(devinfo, dma_attr,
53810115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl);
53910115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
54010115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_allo_dma_mem(): "
54110115c80Sfei feng - Sun Microsystems - Beijing China "failed to alloc handle\n");
54210115c80Sfei feng - Sun Microsystems - Beijing China goto fail1;
54310115c80Sfei feng - Sun Microsystems - Beijing China }
54410115c80Sfei feng - Sun Microsystems - Beijing China
54510115c80Sfei feng - Sun Microsystems - Beijing China /*
54610115c80Sfei feng - Sun Microsystems - Beijing China * Allocate memory
54710115c80Sfei feng - Sun Microsystems - Beijing China */
54810115c80Sfei feng - Sun Microsystems - Beijing China err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p,
54910115c80Sfei feng - Sun Microsystems - Beijing China alloc_flags, DDI_DMA_SLEEP, NULL, &dma_p->mem_va,
55010115c80Sfei feng - Sun Microsystems - Beijing China &dma_p->alength, &dma_p->acc_hdl);
55110115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
55210115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_alloc_dma_mem(): "
55310115c80Sfei feng - Sun Microsystems - Beijing China "failed to alloc mem\n");
55410115c80Sfei feng - Sun Microsystems - Beijing China goto fail2;
55510115c80Sfei feng - Sun Microsystems - Beijing China }
55610115c80Sfei feng - Sun Microsystems - Beijing China
55710115c80Sfei feng - Sun Microsystems - Beijing China /*
55810115c80Sfei feng - Sun Microsystems - Beijing China * Bind the two together
55910115c80Sfei feng - Sun Microsystems - Beijing China */
56010115c80Sfei feng - Sun Microsystems - Beijing China err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL,
56110115c80Sfei feng - Sun Microsystems - Beijing China dma_p->mem_va, dma_p->alength, bind_flags,
56210115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SLEEP, NULL, &dma_p->cookie, &dma_p->ncookies);
56310115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_DMA_MAPPED) {
56410115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_alloc_dma_mem(): "
56510115c80Sfei feng - Sun Microsystems - Beijing China "failed to bind handle\n");
56610115c80Sfei feng - Sun Microsystems - Beijing China goto fail3;
56710115c80Sfei feng - Sun Microsystems - Beijing China }
56810115c80Sfei feng - Sun Microsystems - Beijing China
56910115c80Sfei feng - Sun Microsystems - Beijing China if (dma_p->ncookies != 1) {
57010115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_alloc_dma_mem(): "
57110115c80Sfei feng - Sun Microsystems - Beijing China "failed to alloc cookies\n");
57210115c80Sfei feng - Sun Microsystems - Beijing China goto fail4;
57310115c80Sfei feng - Sun Microsystems - Beijing China }
57410115c80Sfei feng - Sun Microsystems - Beijing China
57510115c80Sfei feng - Sun Microsystems - Beijing China dma_p->nslots = ~0U;
57610115c80Sfei feng - Sun Microsystems - Beijing China dma_p->size = ~0U;
57710115c80Sfei feng - Sun Microsystems - Beijing China dma_p->token = ~0U;
57810115c80Sfei feng - Sun Microsystems - Beijing China dma_p->offset = 0;
57910115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
58010115c80Sfei feng - Sun Microsystems - Beijing China
58110115c80Sfei feng - Sun Microsystems - Beijing China fail4:
58210115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_unbind_handle(dma_p->dma_hdl);
58310115c80Sfei feng - Sun Microsystems - Beijing China fail3:
58410115c80Sfei feng - Sun Microsystems - Beijing China ddi_dma_mem_free(&dma_p->acc_hdl);
58510115c80Sfei feng - Sun Microsystems - Beijing China fail2:
58610115c80Sfei feng - Sun Microsystems - Beijing China ddi_dma_free_handle(&dma_p->dma_hdl);
58710115c80Sfei feng - Sun Microsystems - Beijing China fail1:
58810115c80Sfei feng - Sun Microsystems - Beijing China return (err);
58910115c80Sfei feng - Sun Microsystems - Beijing China }
59010115c80Sfei feng - Sun Microsystems - Beijing China
59110115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_free_dma_mem(struct dma_area * dma_p)59210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_dma_mem(struct dma_area *dma_p)
59310115c80Sfei feng - Sun Microsystems - Beijing China {
59410115c80Sfei feng - Sun Microsystems - Beijing China if (dma_p->dma_hdl != NULL) {
59510115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_unbind_handle(dma_p->dma_hdl);
59610115c80Sfei feng - Sun Microsystems - Beijing China if (dma_p->acc_hdl != NULL) {
59710115c80Sfei feng - Sun Microsystems - Beijing China ddi_dma_mem_free(&dma_p->acc_hdl);
59810115c80Sfei feng - Sun Microsystems - Beijing China dma_p->acc_hdl = NULL;
59910115c80Sfei feng - Sun Microsystems - Beijing China }
60010115c80Sfei feng - Sun Microsystems - Beijing China ddi_dma_free_handle(&dma_p->dma_hdl);
60110115c80Sfei feng - Sun Microsystems - Beijing China dma_p->ncookies = 0;
60210115c80Sfei feng - Sun Microsystems - Beijing China dma_p->dma_hdl = NULL;
60310115c80Sfei feng - Sun Microsystems - Beijing China }
60410115c80Sfei feng - Sun Microsystems - Beijing China }
60510115c80Sfei feng - Sun Microsystems - Beijing China
60610115c80Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/
60710115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_alloc_tx_ring(struct rt2661_softc * sc,struct rt2661_tx_ring * ring,int count)60810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_alloc_tx_ring(struct rt2661_softc *sc,
60910115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_ring *ring, int count)
61010115c80Sfei feng - Sun Microsystems - Beijing China {
61110115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_desc *desc;
61210115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_data *data;
61310115c80Sfei feng - Sun Microsystems - Beijing China int i, err, size, len;
61410115c80Sfei feng - Sun Microsystems - Beijing China
61510115c80Sfei feng - Sun Microsystems - Beijing China size = count * RT2661_TX_DESC_SIZE;
61610115c80Sfei feng - Sun Microsystems - Beijing China len = count * sizeof (struct rt2661_tx_data);
61710115c80Sfei feng - Sun Microsystems - Beijing China
61810115c80Sfei feng - Sun Microsystems - Beijing China ring->count = count;
61910115c80Sfei feng - Sun Microsystems - Beijing China ring->queued = 0;
62010115c80Sfei feng - Sun Microsystems - Beijing China ring->cur = 0;
62110115c80Sfei feng - Sun Microsystems - Beijing China ring->next = 0;
62210115c80Sfei feng - Sun Microsystems - Beijing China ring->stat = 0;
62310115c80Sfei feng - Sun Microsystems - Beijing China
62410115c80Sfei feng - Sun Microsystems - Beijing China err = rt2661_alloc_dma_mem(sc->sc_dev, &rt2661_dma_attr, size,
62510115c80Sfei feng - Sun Microsystems - Beijing China &rt2661_desc_accattr, DDI_DMA_CONSISTENT,
62610115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
62710115c80Sfei feng - Sun Microsystems - Beijing China &ring->txdesc_dma);
62810115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
62910115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_alloc_tx_ring(): "
63010115c80Sfei feng - Sun Microsystems - Beijing China "failed to alloc dma mem\n");
63110115c80Sfei feng - Sun Microsystems - Beijing China goto fail1;
63210115c80Sfei feng - Sun Microsystems - Beijing China }
63310115c80Sfei feng - Sun Microsystems - Beijing China
63410115c80Sfei feng - Sun Microsystems - Beijing China ring->desc = (struct rt2661_tx_desc *)ring->txdesc_dma.mem_va;
63510115c80Sfei feng - Sun Microsystems - Beijing China (void) bzero(ring->desc, size);
63610115c80Sfei feng - Sun Microsystems - Beijing China ring->paddr = ring->txdesc_dma.cookie.dmac_address;
63710115c80Sfei feng - Sun Microsystems - Beijing China
63810115c80Sfei feng - Sun Microsystems - Beijing China ring->data = kmem_zalloc(len, KM_NOSLEEP);
63910115c80Sfei feng - Sun Microsystems - Beijing China if (ring->data == NULL) {
64010115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_alloc_tx_ring(): "
64110115c80Sfei feng - Sun Microsystems - Beijing China "failed to alloc tx buffer\n");
64210115c80Sfei feng - Sun Microsystems - Beijing China goto fail2;
64310115c80Sfei feng - Sun Microsystems - Beijing China }
64410115c80Sfei feng - Sun Microsystems - Beijing China
64510115c80Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < count; i++) {
64610115c80Sfei feng - Sun Microsystems - Beijing China desc = &ring->desc[i];
64710115c80Sfei feng - Sun Microsystems - Beijing China data = &ring->data[i];
64810115c80Sfei feng - Sun Microsystems - Beijing China err = rt2661_alloc_dma_mem(sc->sc_dev,
64910115c80Sfei feng - Sun Microsystems - Beijing China &rt2661_dma_attr, sc->sc_dmabuf_size,
65010115c80Sfei feng - Sun Microsystems - Beijing China &rt2661_buf_accattr, DDI_DMA_CONSISTENT,
65110115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
65210115c80Sfei feng - Sun Microsystems - Beijing China &data->txdata_dma);
65310115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
65410115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_DMA,
65510115c80Sfei feng - Sun Microsystems - Beijing China "rwd: rt2661_alloc_tx_ring(): "
65610115c80Sfei feng - Sun Microsystems - Beijing China "failed to alloc tx buffer dma\n");
65710115c80Sfei feng - Sun Microsystems - Beijing China while (i >= 0) {
65810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_dma_mem(&ring->data[i].txdata_dma);
65910115c80Sfei feng - Sun Microsystems - Beijing China i--;
66010115c80Sfei feng - Sun Microsystems - Beijing China }
66110115c80Sfei feng - Sun Microsystems - Beijing China goto fail3;
66210115c80Sfei feng - Sun Microsystems - Beijing China }
66310115c80Sfei feng - Sun Microsystems - Beijing China desc->addr[0] = data->txdata_dma.cookie.dmac_address;
66410115c80Sfei feng - Sun Microsystems - Beijing China data->buf = data->txdata_dma.mem_va;
66510115c80Sfei feng - Sun Microsystems - Beijing China data->paddr = data->txdata_dma.cookie.dmac_address;
66610115c80Sfei feng - Sun Microsystems - Beijing China }
66710115c80Sfei feng - Sun Microsystems - Beijing China
66810115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
66910115c80Sfei feng - Sun Microsystems - Beijing China 0, size, DDI_DMA_SYNC_FORDEV);
67010115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
67110115c80Sfei feng - Sun Microsystems - Beijing China fail3:
67210115c80Sfei feng - Sun Microsystems - Beijing China if (ring->data)
67310115c80Sfei feng - Sun Microsystems - Beijing China kmem_free(ring->data,
67410115c80Sfei feng - Sun Microsystems - Beijing China count * sizeof (struct rt2661_tx_data));
67510115c80Sfei feng - Sun Microsystems - Beijing China fail2:
67610115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_dma_mem(&ring->txdesc_dma);
67710115c80Sfei feng - Sun Microsystems - Beijing China fail1:
67810115c80Sfei feng - Sun Microsystems - Beijing China return (err);
67910115c80Sfei feng - Sun Microsystems - Beijing China }
68010115c80Sfei feng - Sun Microsystems - Beijing China
68110115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_reset_tx_ring(struct rt2661_softc * sc,struct rt2661_tx_ring * ring)68210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_reset_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring)
68310115c80Sfei feng - Sun Microsystems - Beijing China {
68410115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_desc *desc;
68510115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_data *data;
68610115c80Sfei feng - Sun Microsystems - Beijing China int i;
68710115c80Sfei feng - Sun Microsystems - Beijing China
68810115c80Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < ring->count; i++) {
68910115c80Sfei feng - Sun Microsystems - Beijing China desc = &ring->desc[i];
69010115c80Sfei feng - Sun Microsystems - Beijing China data = &ring->data[i];
69110115c80Sfei feng - Sun Microsystems - Beijing China
69210115c80Sfei feng - Sun Microsystems - Beijing China if (data->ni != NULL) {
69310115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_free_node(data->ni);
69410115c80Sfei feng - Sun Microsystems - Beijing China data->ni = NULL;
69510115c80Sfei feng - Sun Microsystems - Beijing China }
69610115c80Sfei feng - Sun Microsystems - Beijing China
69710115c80Sfei feng - Sun Microsystems - Beijing China desc->flags = 0;
69810115c80Sfei feng - Sun Microsystems - Beijing China }
69910115c80Sfei feng - Sun Microsystems - Beijing China
70010115c80Sfei feng - Sun Microsystems - Beijing China if (!RT2661_IS_FASTREBOOT(sc))
70110115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl, 0,
70210115c80Sfei feng - Sun Microsystems - Beijing China ring->count * sizeof (struct rt2661_tx_desc),
70310115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV);
70410115c80Sfei feng - Sun Microsystems - Beijing China
70510115c80Sfei feng - Sun Microsystems - Beijing China ring->queued = 0;
70610115c80Sfei feng - Sun Microsystems - Beijing China ring->cur = ring->next = ring->stat = 0;
70710115c80Sfei feng - Sun Microsystems - Beijing China }
70810115c80Sfei feng - Sun Microsystems - Beijing China
70910115c80Sfei feng - Sun Microsystems - Beijing China
71010115c80Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/
71110115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_free_tx_ring(struct rt2661_softc * sc,struct rt2661_tx_ring * ring)71210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring)
71310115c80Sfei feng - Sun Microsystems - Beijing China {
71410115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_data *data;
71510115c80Sfei feng - Sun Microsystems - Beijing China int i;
71610115c80Sfei feng - Sun Microsystems - Beijing China
71710115c80Sfei feng - Sun Microsystems - Beijing China if (ring->desc != NULL) {
71810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_dma_mem(&ring->txdesc_dma);
71910115c80Sfei feng - Sun Microsystems - Beijing China }
72010115c80Sfei feng - Sun Microsystems - Beijing China
72110115c80Sfei feng - Sun Microsystems - Beijing China if (ring->data != NULL) {
72210115c80Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < ring->count; i++) {
72310115c80Sfei feng - Sun Microsystems - Beijing China data = &ring->data[i];
72410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_dma_mem(&data->txdata_dma);
72510115c80Sfei feng - Sun Microsystems - Beijing China if (data->ni != NULL) {
72610115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_free_node(data->ni);
72710115c80Sfei feng - Sun Microsystems - Beijing China data->ni = NULL;
72810115c80Sfei feng - Sun Microsystems - Beijing China }
72910115c80Sfei feng - Sun Microsystems - Beijing China }
73010115c80Sfei feng - Sun Microsystems - Beijing China kmem_free(ring->data,
73110115c80Sfei feng - Sun Microsystems - Beijing China ring->count * sizeof (struct rt2661_tx_data));
73210115c80Sfei feng - Sun Microsystems - Beijing China }
73310115c80Sfei feng - Sun Microsystems - Beijing China }
73410115c80Sfei feng - Sun Microsystems - Beijing China
73510115c80Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/
73610115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_alloc_rx_ring(struct rt2661_softc * sc,struct rt2661_rx_ring * ring,int count)73710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_alloc_rx_ring(struct rt2661_softc *sc,
73810115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_rx_ring *ring, int count)
73910115c80Sfei feng - Sun Microsystems - Beijing China {
74010115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_rx_desc *desc;
74110115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_rx_data *data;
74210115c80Sfei feng - Sun Microsystems - Beijing China int i, err, len, size;
74310115c80Sfei feng - Sun Microsystems - Beijing China
74410115c80Sfei feng - Sun Microsystems - Beijing China size = count * RT2661_RX_DESC_SIZE;
74510115c80Sfei feng - Sun Microsystems - Beijing China len = count * sizeof (struct rt2661_rx_data);
74610115c80Sfei feng - Sun Microsystems - Beijing China
74710115c80Sfei feng - Sun Microsystems - Beijing China ring->count = count;
74810115c80Sfei feng - Sun Microsystems - Beijing China ring->cur = 0;
74910115c80Sfei feng - Sun Microsystems - Beijing China ring->next = 0;
75010115c80Sfei feng - Sun Microsystems - Beijing China
75110115c80Sfei feng - Sun Microsystems - Beijing China err = rt2661_alloc_dma_mem(sc->sc_dev, &rt2661_dma_attr, size,
75210115c80Sfei feng - Sun Microsystems - Beijing China &rt2661_desc_accattr, DDI_DMA_CONSISTENT,
75310115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
75410115c80Sfei feng - Sun Microsystems - Beijing China &ring->rxdesc_dma);
75510115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
75610115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_alloc_rx_ring(): "
75710115c80Sfei feng - Sun Microsystems - Beijing China "failed to alloc dma mem\n");
75810115c80Sfei feng - Sun Microsystems - Beijing China goto fail1;
75910115c80Sfei feng - Sun Microsystems - Beijing China }
76010115c80Sfei feng - Sun Microsystems - Beijing China
76110115c80Sfei feng - Sun Microsystems - Beijing China ring->desc = (struct rt2661_rx_desc *)ring->rxdesc_dma.mem_va;
76210115c80Sfei feng - Sun Microsystems - Beijing China (void) bzero(ring->desc, size);
76310115c80Sfei feng - Sun Microsystems - Beijing China ring->paddr = ring->rxdesc_dma.cookie.dmac_address;
76410115c80Sfei feng - Sun Microsystems - Beijing China
76510115c80Sfei feng - Sun Microsystems - Beijing China ring->data = kmem_zalloc(len, KM_NOSLEEP);
76610115c80Sfei feng - Sun Microsystems - Beijing China if (ring->data == NULL) {
76710115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_alloc_rx_ring(): "
76810115c80Sfei feng - Sun Microsystems - Beijing China "failed to alloc rx buffer\n");
76910115c80Sfei feng - Sun Microsystems - Beijing China goto fail2;
77010115c80Sfei feng - Sun Microsystems - Beijing China }
77110115c80Sfei feng - Sun Microsystems - Beijing China
77210115c80Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < count; i++) {
77310115c80Sfei feng - Sun Microsystems - Beijing China desc = &ring->desc[i];
77410115c80Sfei feng - Sun Microsystems - Beijing China data = &ring->data[i];
77510115c80Sfei feng - Sun Microsystems - Beijing China err = rt2661_alloc_dma_mem(sc->sc_dev,
77610115c80Sfei feng - Sun Microsystems - Beijing China &rt2661_dma_attr, sc->sc_dmabuf_size,
77710115c80Sfei feng - Sun Microsystems - Beijing China &rt2661_buf_accattr, DDI_DMA_CONSISTENT,
77810115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
77910115c80Sfei feng - Sun Microsystems - Beijing China &data->rxdata_dma);
78010115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
78110115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_DMA,
78210115c80Sfei feng - Sun Microsystems - Beijing China "rwd: rt2661_alloc_rx_ring(): "
78310115c80Sfei feng - Sun Microsystems - Beijing China "failed to alloc rx buffer dma\n");
78410115c80Sfei feng - Sun Microsystems - Beijing China while (i >= 0) {
78510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_dma_mem(&ring->data[i].rxdata_dma);
78610115c80Sfei feng - Sun Microsystems - Beijing China i--;
78710115c80Sfei feng - Sun Microsystems - Beijing China }
78810115c80Sfei feng - Sun Microsystems - Beijing China goto fail3;
78910115c80Sfei feng - Sun Microsystems - Beijing China }
79010115c80Sfei feng - Sun Microsystems - Beijing China data->buf = data->rxdata_dma.mem_va;
79110115c80Sfei feng - Sun Microsystems - Beijing China data->paddr = data->rxdata_dma.cookie.dmac_address;
79210115c80Sfei feng - Sun Microsystems - Beijing China desc->flags = LE_32(RT2661_RX_BUSY);
79310115c80Sfei feng - Sun Microsystems - Beijing China desc->physaddr = LE_32(data->paddr);
79410115c80Sfei feng - Sun Microsystems - Beijing China }
79510115c80Sfei feng - Sun Microsystems - Beijing China
79610115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl,
79710115c80Sfei feng - Sun Microsystems - Beijing China 0, size, DDI_DMA_SYNC_FORDEV);
79810115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
79910115c80Sfei feng - Sun Microsystems - Beijing China fail3:
80010115c80Sfei feng - Sun Microsystems - Beijing China if (ring->data)
80110115c80Sfei feng - Sun Microsystems - Beijing China kmem_free(ring->data,
80210115c80Sfei feng - Sun Microsystems - Beijing China count * sizeof (struct rt2661_rx_data));
80310115c80Sfei feng - Sun Microsystems - Beijing China fail2:
80410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_dma_mem(&ring->rxdesc_dma);
80510115c80Sfei feng - Sun Microsystems - Beijing China fail1:
80610115c80Sfei feng - Sun Microsystems - Beijing China return (err);
80710115c80Sfei feng - Sun Microsystems - Beijing China }
80810115c80Sfei feng - Sun Microsystems - Beijing China
80910115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_reset_rx_ring(struct rt2661_softc * sc,struct rt2661_rx_ring * ring)81010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_reset_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring)
81110115c80Sfei feng - Sun Microsystems - Beijing China {
81210115c80Sfei feng - Sun Microsystems - Beijing China int i;
81310115c80Sfei feng - Sun Microsystems - Beijing China
81410115c80Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < ring->count; i++)
81510115c80Sfei feng - Sun Microsystems - Beijing China ring->desc[i].flags = LE_32(RT2661_RX_BUSY);
81610115c80Sfei feng - Sun Microsystems - Beijing China
81710115c80Sfei feng - Sun Microsystems - Beijing China if (!RT2661_IS_FASTREBOOT(sc))
81810115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl, 0,
81910115c80Sfei feng - Sun Microsystems - Beijing China ring->count * sizeof (struct rt2661_rx_ring),
82010115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORKERNEL);
82110115c80Sfei feng - Sun Microsystems - Beijing China
82210115c80Sfei feng - Sun Microsystems - Beijing China ring->cur = ring->next = 0;
82310115c80Sfei feng - Sun Microsystems - Beijing China }
82410115c80Sfei feng - Sun Microsystems - Beijing China
82510115c80Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/
82610115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_free_rx_ring(struct rt2661_softc * sc,struct rt2661_rx_ring * ring)82710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring)
82810115c80Sfei feng - Sun Microsystems - Beijing China {
82910115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_rx_data *data;
83010115c80Sfei feng - Sun Microsystems - Beijing China int i;
83110115c80Sfei feng - Sun Microsystems - Beijing China
83210115c80Sfei feng - Sun Microsystems - Beijing China if (ring->desc != NULL) {
83310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_dma_mem(&ring->rxdesc_dma);
83410115c80Sfei feng - Sun Microsystems - Beijing China }
83510115c80Sfei feng - Sun Microsystems - Beijing China
83610115c80Sfei feng - Sun Microsystems - Beijing China if (ring->data != NULL) {
83710115c80Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < ring->count; i++) {
83810115c80Sfei feng - Sun Microsystems - Beijing China data = &ring->data[i];
83910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_dma_mem(&data->rxdata_dma);
84010115c80Sfei feng - Sun Microsystems - Beijing China }
84110115c80Sfei feng - Sun Microsystems - Beijing China kmem_free(ring->data,
84210115c80Sfei feng - Sun Microsystems - Beijing China ring->count * sizeof (struct rt2661_rx_data));
84310115c80Sfei feng - Sun Microsystems - Beijing China }
84410115c80Sfei feng - Sun Microsystems - Beijing China }
84510115c80Sfei feng - Sun Microsystems - Beijing China
84610115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_tx_dma_intr(struct rt2661_softc * sc,struct rt2661_tx_ring * ring)84710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *ring)
84810115c80Sfei feng - Sun Microsystems - Beijing China {
84910115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_desc *desc;
85010115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_data *data;
85110115c80Sfei feng - Sun Microsystems - Beijing China
85210115c80Sfei feng - Sun Microsystems - Beijing China for (;;) {
85310115c80Sfei feng - Sun Microsystems - Beijing China desc = &ring->desc[ring->next];
85410115c80Sfei feng - Sun Microsystems - Beijing China data = &ring->data[ring->next];
85510115c80Sfei feng - Sun Microsystems - Beijing China
85610115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
85710115c80Sfei feng - Sun Microsystems - Beijing China ring->next * RT2661_TX_DESC_SIZE,
85810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_TX_DESC_SIZE,
85910115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORKERNEL);
86010115c80Sfei feng - Sun Microsystems - Beijing China
86110115c80Sfei feng - Sun Microsystems - Beijing China if ((LE_32(desc->flags) & RT2661_TX_BUSY) ||
86210115c80Sfei feng - Sun Microsystems - Beijing China !(LE_32(desc->flags) & RT2661_TX_VALID))
86310115c80Sfei feng - Sun Microsystems - Beijing China break;
86410115c80Sfei feng - Sun Microsystems - Beijing China
86510115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(data->txdata_dma.dma_hdl,
86610115c80Sfei feng - Sun Microsystems - Beijing China 0, sc->sc_dmabuf_size,
86710115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV);
86810115c80Sfei feng - Sun Microsystems - Beijing China
86910115c80Sfei feng - Sun Microsystems - Beijing China /* descriptor is no longer valid */
87010115c80Sfei feng - Sun Microsystems - Beijing China desc->flags &= ~LE_32(RT2661_TX_VALID);
87110115c80Sfei feng - Sun Microsystems - Beijing China
87210115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
87310115c80Sfei feng - Sun Microsystems - Beijing China ring->next * RT2661_TX_DESC_SIZE,
87410115c80Sfei feng - Sun Microsystems - Beijing China RT2661_TX_DESC_SIZE,
87510115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV);
87610115c80Sfei feng - Sun Microsystems - Beijing China
87710115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_dma_intr(): "
87810115c80Sfei feng - Sun Microsystems - Beijing China "tx dma done q=%p idx=%u\n", ring, ring->next);
87910115c80Sfei feng - Sun Microsystems - Beijing China
88010115c80Sfei feng - Sun Microsystems - Beijing China if (++ring->next >= ring->count) /* faster than % count */
88110115c80Sfei feng - Sun Microsystems - Beijing China ring->next = 0;
88210115c80Sfei feng - Sun Microsystems - Beijing China }
88310115c80Sfei feng - Sun Microsystems - Beijing China }
88410115c80Sfei feng - Sun Microsystems - Beijing China
88510115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_tx_intr(struct rt2661_softc * sc)88610115c80Sfei feng - Sun Microsystems - Beijing China rt2661_tx_intr(struct rt2661_softc *sc)
88710115c80Sfei feng - Sun Microsystems - Beijing China {
88810115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
88910115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_ring *ring;
89010115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_data *data;
89110115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_node *rn;
89210115c80Sfei feng - Sun Microsystems - Beijing China
89310115c80Sfei feng - Sun Microsystems - Beijing China uint32_t val;
89410115c80Sfei feng - Sun Microsystems - Beijing China int qid, retrycnt;
89510115c80Sfei feng - Sun Microsystems - Beijing China
89610115c80Sfei feng - Sun Microsystems - Beijing China for (;;) {
89710115c80Sfei feng - Sun Microsystems - Beijing China val = RT2661_READ(sc, RT2661_STA_CSR4);
89810115c80Sfei feng - Sun Microsystems - Beijing China if (!(val & RT2661_TX_STAT_VALID))
89910115c80Sfei feng - Sun Microsystems - Beijing China break;
90010115c80Sfei feng - Sun Microsystems - Beijing China
90110115c80Sfei feng - Sun Microsystems - Beijing China /* retrieve the queue in which this frame was send */
90210115c80Sfei feng - Sun Microsystems - Beijing China qid = RT2661_TX_QID(val);
90310115c80Sfei feng - Sun Microsystems - Beijing China ring = (qid <= 3) ? &sc->txq[qid] : &sc->mgtq;
90410115c80Sfei feng - Sun Microsystems - Beijing China
90510115c80Sfei feng - Sun Microsystems - Beijing China /* retrieve rate control algorithm context */
90610115c80Sfei feng - Sun Microsystems - Beijing China data = &ring->data[ring->stat];
90710115c80Sfei feng - Sun Microsystems - Beijing China rn = (struct rt2661_node *)data->ni;
90810115c80Sfei feng - Sun Microsystems - Beijing China
90910115c80Sfei feng - Sun Microsystems - Beijing China /* if no frame has been sent, ignore */
91010115c80Sfei feng - Sun Microsystems - Beijing China if (rn == NULL) {
91110115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): "
91210115c80Sfei feng - Sun Microsystems - Beijing China "no frame has been send, ignore\n");
91310115c80Sfei feng - Sun Microsystems - Beijing China continue;
91410115c80Sfei feng - Sun Microsystems - Beijing China }
91510115c80Sfei feng - Sun Microsystems - Beijing China
91610115c80Sfei feng - Sun Microsystems - Beijing China switch (RT2661_TX_RESULT(val)) {
91710115c80Sfei feng - Sun Microsystems - Beijing China case RT2661_TX_SUCCESS:
91810115c80Sfei feng - Sun Microsystems - Beijing China retrycnt = RT2661_TX_RETRYCNT(val);
91910115c80Sfei feng - Sun Microsystems - Beijing China
92010115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): "
92110115c80Sfei feng - Sun Microsystems - Beijing China "data frame sent successfully after "
92210115c80Sfei feng - Sun Microsystems - Beijing China "%d retries\n", retrycnt);
92310115c80Sfei feng - Sun Microsystems - Beijing China rn->amn.amn_txcnt++;
92410115c80Sfei feng - Sun Microsystems - Beijing China if (retrycnt > 0) {
92510115c80Sfei feng - Sun Microsystems - Beijing China rn->amn.amn_retrycnt++;
92610115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_retries++;
92710115c80Sfei feng - Sun Microsystems - Beijing China }
92810115c80Sfei feng - Sun Microsystems - Beijing China break;
92910115c80Sfei feng - Sun Microsystems - Beijing China case RT2661_TX_RETRY_FAIL:
93010115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): "
93110115c80Sfei feng - Sun Microsystems - Beijing China "sending data frame failed (too much retries)\n");
93210115c80Sfei feng - Sun Microsystems - Beijing China rn->amn.amn_txcnt++;
93310115c80Sfei feng - Sun Microsystems - Beijing China rn->amn.amn_retrycnt++;
93410115c80Sfei feng - Sun Microsystems - Beijing China break;
93510115c80Sfei feng - Sun Microsystems - Beijing China default:
93610115c80Sfei feng - Sun Microsystems - Beijing China /* other failure */
93710115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr():"
93810115c80Sfei feng - Sun Microsystems - Beijing China "sending data frame failed 0x%08x\n", val);
93910115c80Sfei feng - Sun Microsystems - Beijing China }
94010115c80Sfei feng - Sun Microsystems - Beijing China
94110115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): "
94210115c80Sfei feng - Sun Microsystems - Beijing China "tx done q=%d idx=%u\n", qid, ring->stat);
94310115c80Sfei feng - Sun Microsystems - Beijing China
94410115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_free_node(data->ni);
94510115c80Sfei feng - Sun Microsystems - Beijing China data->ni = NULL;
94610115c80Sfei feng - Sun Microsystems - Beijing China
94710115c80Sfei feng - Sun Microsystems - Beijing China ring->queued--;
94810115c80Sfei feng - Sun Microsystems - Beijing China
94910115c80Sfei feng - Sun Microsystems - Beijing China /* faster than % count */
95010115c80Sfei feng - Sun Microsystems - Beijing China if (++ring->stat >= ring->count)
95110115c80Sfei feng - Sun Microsystems - Beijing China ring->stat = 0;
95210115c80Sfei feng - Sun Microsystems - Beijing China
95310115c80Sfei feng - Sun Microsystems - Beijing China if (sc->sc_need_sched) {
95410115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_need_sched = 0;
95510115c80Sfei feng - Sun Microsystems - Beijing China mac_tx_update(ic->ic_mach);
95610115c80Sfei feng - Sun Microsystems - Beijing China }
95710115c80Sfei feng - Sun Microsystems - Beijing China }
95810115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_timer = 0;
95910115c80Sfei feng - Sun Microsystems - Beijing China }
96010115c80Sfei feng - Sun Microsystems - Beijing China
96110115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_rx_intr(struct rt2661_softc * sc)96210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rx_intr(struct rt2661_softc *sc)
96310115c80Sfei feng - Sun Microsystems - Beijing China {
96410115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
96510115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_rx_ring *ring;
96610115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_rx_desc *desc;
96710115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_rx_data *data;
96810115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211_frame *wh;
96910115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni;
97010115c80Sfei feng - Sun Microsystems - Beijing China
97110115c80Sfei feng - Sun Microsystems - Beijing China mblk_t *m;
97210115c80Sfei feng - Sun Microsystems - Beijing China uint8_t *rxbuf;
97310115c80Sfei feng - Sun Microsystems - Beijing China uint32_t pktlen;
97410115c80Sfei feng - Sun Microsystems - Beijing China
97510115c80Sfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_rxlock);
97610115c80Sfei feng - Sun Microsystems - Beijing China ring = &sc->rxq;
97710115c80Sfei feng - Sun Microsystems - Beijing China
97810115c80Sfei feng - Sun Microsystems - Beijing China for (;;) {
97910115c80Sfei feng - Sun Microsystems - Beijing China int rssi;
98010115c80Sfei feng - Sun Microsystems - Beijing China
98110115c80Sfei feng - Sun Microsystems - Beijing China desc = &ring->desc[ring->cur];
98210115c80Sfei feng - Sun Microsystems - Beijing China data = &ring->data[ring->cur];
98310115c80Sfei feng - Sun Microsystems - Beijing China
98410115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl,
98510115c80Sfei feng - Sun Microsystems - Beijing China ring->cur * RT2661_RX_DESC_SIZE,
98610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_RX_DESC_SIZE,
98710115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORKERNEL);
98810115c80Sfei feng - Sun Microsystems - Beijing China
98910115c80Sfei feng - Sun Microsystems - Beijing China
99010115c80Sfei feng - Sun Microsystems - Beijing China if (LE_32(desc->flags) & RT2661_RX_BUSY)
99110115c80Sfei feng - Sun Microsystems - Beijing China break;
99210115c80Sfei feng - Sun Microsystems - Beijing China
99310115c80Sfei feng - Sun Microsystems - Beijing China if ((LE_32(desc->flags) & RT2661_RX_PHY_ERROR) ||
99410115c80Sfei feng - Sun Microsystems - Beijing China (LE_32(desc->flags) & RT2661_RX_CRC_ERROR)) {
99510115c80Sfei feng - Sun Microsystems - Beijing China /*
99610115c80Sfei feng - Sun Microsystems - Beijing China * This should not happen since we did not request
99710115c80Sfei feng - Sun Microsystems - Beijing China * to receive those frames when we filled TXRX_CSR0.
99810115c80Sfei feng - Sun Microsystems - Beijing China */
99910115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_intr(): "
100010115c80Sfei feng - Sun Microsystems - Beijing China "PHY or CRC error flags 0x%08x\n",
100110115c80Sfei feng - Sun Microsystems - Beijing China LE_32(desc->flags));
100210115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_err++;
100310115c80Sfei feng - Sun Microsystems - Beijing China goto skip;
100410115c80Sfei feng - Sun Microsystems - Beijing China }
100510115c80Sfei feng - Sun Microsystems - Beijing China
100610115c80Sfei feng - Sun Microsystems - Beijing China if ((LE_32(desc->flags) & RT2661_RX_CIPHER_MASK) != 0) {
100710115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_err++;
100810115c80Sfei feng - Sun Microsystems - Beijing China goto skip;
100910115c80Sfei feng - Sun Microsystems - Beijing China }
101010115c80Sfei feng - Sun Microsystems - Beijing China
101110115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(data->rxdata_dma.dma_hdl,
101210115c80Sfei feng - Sun Microsystems - Beijing China 0, sc->sc_dmabuf_size,
101310115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORCPU);
101410115c80Sfei feng - Sun Microsystems - Beijing China
101510115c80Sfei feng - Sun Microsystems - Beijing China rxbuf = (uint8_t *)data->rxdata_dma.mem_va;
101610115c80Sfei feng - Sun Microsystems - Beijing China desc->physaddr = LE_32(data->rxdata_dma.cookie.dmac_address);
101710115c80Sfei feng - Sun Microsystems - Beijing China pktlen = (LE_32(desc->flags) >> 16) & 0xfff;
101810115c80Sfei feng - Sun Microsystems - Beijing China if ((pktlen < sizeof (struct ieee80211_frame_min)) ||
101910115c80Sfei feng - Sun Microsystems - Beijing China (pktlen > sc->sc_dmabuf_size)) {
102010115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_intr(): "
102110115c80Sfei feng - Sun Microsystems - Beijing China "bad fram length=%u\n", pktlen);
102210115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_err++;
102310115c80Sfei feng - Sun Microsystems - Beijing China goto skip;
102410115c80Sfei feng - Sun Microsystems - Beijing China }
102510115c80Sfei feng - Sun Microsystems - Beijing China
102610115c80Sfei feng - Sun Microsystems - Beijing China if ((m = allocb(pktlen, BPRI_MED)) == NULL) {
102710115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_intr(): "
102810115c80Sfei feng - Sun Microsystems - Beijing China "allocate mblk failed.\n");
102910115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_nobuf++;
103010115c80Sfei feng - Sun Microsystems - Beijing China goto skip;
103110115c80Sfei feng - Sun Microsystems - Beijing China }
103210115c80Sfei feng - Sun Microsystems - Beijing China
103310115c80Sfei feng - Sun Microsystems - Beijing China bcopy(rxbuf, m->b_rptr, pktlen);
103410115c80Sfei feng - Sun Microsystems - Beijing China m->b_wptr += pktlen;
103510115c80Sfei feng - Sun Microsystems - Beijing China
103610115c80Sfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr;
103710115c80Sfei feng - Sun Microsystems - Beijing China ni = ieee80211_find_rxnode(ic, wh);
103810115c80Sfei feng - Sun Microsystems - Beijing China
103910115c80Sfei feng - Sun Microsystems - Beijing China rssi = rt2661_get_rssi(sc, desc->rssi);
104010115c80Sfei feng - Sun Microsystems - Beijing China /* send the frame to the 802.11 layer */
1041c1374a13SSurya Prakki (void) ieee80211_input(ic, m, ni, rssi + 95, 0);
104210115c80Sfei feng - Sun Microsystems - Beijing China
104310115c80Sfei feng - Sun Microsystems - Beijing China sc->avg_rssi = (rssi + 7 * sc->avg_rssi) / 8;
104410115c80Sfei feng - Sun Microsystems - Beijing China
104510115c80Sfei feng - Sun Microsystems - Beijing China /* node is no longer needed */
104610115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_free_node(ni);
104710115c80Sfei feng - Sun Microsystems - Beijing China skip:
104810115c80Sfei feng - Sun Microsystems - Beijing China desc->flags |= LE_32(RT2661_RX_BUSY);
104910115c80Sfei feng - Sun Microsystems - Beijing China
105010115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl,
105110115c80Sfei feng - Sun Microsystems - Beijing China ring->cur * RT2661_RX_DESC_SIZE,
105210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_RX_DESC_SIZE,
105310115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV);
105410115c80Sfei feng - Sun Microsystems - Beijing China
105510115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_rx_intr(): "
105610115c80Sfei feng - Sun Microsystems - Beijing China "rx intr idx=%u\n", sc->rxq.cur);
105710115c80Sfei feng - Sun Microsystems - Beijing China ring->cur = (ring->cur + 1) % RT2661_RX_RING_COUNT;
105810115c80Sfei feng - Sun Microsystems - Beijing China }
105910115c80Sfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_rxlock);
106010115c80Sfei feng - Sun Microsystems - Beijing China }
106110115c80Sfei feng - Sun Microsystems - Beijing China
106210115c80Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/
106310115c80Sfei feng - Sun Microsystems - Beijing China static uint_t
rt2661_softintr(caddr_t data,caddr_t unused)106410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_softintr(caddr_t data, caddr_t unused)
106510115c80Sfei feng - Sun Microsystems - Beijing China {
106610115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)data;
106710115c80Sfei feng - Sun Microsystems - Beijing China
106810115c80Sfei feng - Sun Microsystems - Beijing China if (sc->sc_rx_pend) {
106910115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_pend = 0;
107010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rx_intr(sc);
107110115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_INTR_CLAIMED);
107210115c80Sfei feng - Sun Microsystems - Beijing China }
107310115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_INTR_UNCLAIMED);
107410115c80Sfei feng - Sun Microsystems - Beijing China }
107510115c80Sfei feng - Sun Microsystems - Beijing China
107610115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_tx_cmd(struct rt2661_softc * sc,uint8_t cmd,uint16_t arg)107710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_tx_cmd(struct rt2661_softc *sc, uint8_t cmd, uint16_t arg)
107810115c80Sfei feng - Sun Microsystems - Beijing China {
107910115c80Sfei feng - Sun Microsystems - Beijing China if (RT2661_READ(sc, RT2661_H2M_MAILBOX_CSR) & RT2661_H2M_BUSY)
108010115c80Sfei feng - Sun Microsystems - Beijing China return (EIO); /* there is already a command pending */
108110115c80Sfei feng - Sun Microsystems - Beijing China
108210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_H2M_MAILBOX_CSR,
108310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_H2M_BUSY | RT2661_TOKEN_NO_INTR << 16 | arg);
108410115c80Sfei feng - Sun Microsystems - Beijing China
108510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_HOST_CMD_CSR, RT2661_KICK_CMD | cmd);
108610115c80Sfei feng - Sun Microsystems - Beijing China
108710115c80Sfei feng - Sun Microsystems - Beijing China return (0);
108810115c80Sfei feng - Sun Microsystems - Beijing China }
108910115c80Sfei feng - Sun Microsystems - Beijing China
109010115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_mcu_wakeup(struct rt2661_softc * sc)109110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_mcu_wakeup(struct rt2661_softc *sc)
109210115c80Sfei feng - Sun Microsystems - Beijing China {
109310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MAC_CSR11, 5 << 16);
109410115c80Sfei feng - Sun Microsystems - Beijing China
109510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_SOFT_RESET_CSR, 0x7);
109610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_IO_CNTL_CSR, 0x18);
109710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_PCI_USEC_CSR, 0x20);
109810115c80Sfei feng - Sun Microsystems - Beijing China
109910115c80Sfei feng - Sun Microsystems - Beijing China /* send wakeup command to MCU */
110010115c80Sfei feng - Sun Microsystems - Beijing China (void) rt2661_tx_cmd(sc, RT2661_MCU_CMD_WAKEUP, 0);
110110115c80Sfei feng - Sun Microsystems - Beijing China }
110210115c80Sfei feng - Sun Microsystems - Beijing China
110310115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_mcu_cmd_intr(struct rt2661_softc * sc)110410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_mcu_cmd_intr(struct rt2661_softc *sc)
110510115c80Sfei feng - Sun Microsystems - Beijing China {
110610115c80Sfei feng - Sun Microsystems - Beijing China (void) RT2661_READ(sc, RT2661_M2H_CMD_DONE_CSR);
110710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_M2H_CMD_DONE_CSR, 0xffffffff);
110810115c80Sfei feng - Sun Microsystems - Beijing China }
110910115c80Sfei feng - Sun Microsystems - Beijing China
111010115c80Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/
111110115c80Sfei feng - Sun Microsystems - Beijing China static uint_t
rt2661_intr(caddr_t arg,caddr_t unused)111210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_intr(caddr_t arg, caddr_t unused)
111310115c80Sfei feng - Sun Microsystems - Beijing China {
111410115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)arg;
111510115c80Sfei feng - Sun Microsystems - Beijing China uint32_t r1, r2;
111610115c80Sfei feng - Sun Microsystems - Beijing China
111710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GLOCK(sc);
111810115c80Sfei feng - Sun Microsystems - Beijing China
111910115c80Sfei feng - Sun Microsystems - Beijing China if (!RT2661_IS_RUNNING(sc) || RT2661_IS_SUSPEND(sc)) {
112010115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
112110115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_INTR_UNCLAIMED);
112210115c80Sfei feng - Sun Microsystems - Beijing China }
112310115c80Sfei feng - Sun Microsystems - Beijing China
112410115c80Sfei feng - Sun Microsystems - Beijing China r1 = RT2661_READ(sc, RT2661_INT_SOURCE_CSR);
112510115c80Sfei feng - Sun Microsystems - Beijing China r2 = RT2661_READ(sc, RT2661_MCU_INT_SOURCE_CSR);
112610115c80Sfei feng - Sun Microsystems - Beijing China if (r1 == 0 && r2 == 0) {
112710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
112810115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_INTR_UNCLAIMED); /* not for us */
112910115c80Sfei feng - Sun Microsystems - Beijing China }
113010115c80Sfei feng - Sun Microsystems - Beijing China
113110115c80Sfei feng - Sun Microsystems - Beijing China /* disable MAC and MCU interrupts */
113210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f);
113310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff);
113410115c80Sfei feng - Sun Microsystems - Beijing China
113510115c80Sfei feng - Sun Microsystems - Beijing China /* acknowledge interrupts */
113610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_INT_SOURCE_CSR, r1);
113710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, r2);
113810115c80Sfei feng - Sun Microsystems - Beijing China
113910115c80Sfei feng - Sun Microsystems - Beijing China if (r1 & RT2661_MGT_DONE) {
114010115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
114110115c80Sfei feng - Sun Microsystems - Beijing China "RT2661_MGT_DONE\n");
114210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_tx_dma_intr(sc, &sc->mgtq);
114310115c80Sfei feng - Sun Microsystems - Beijing China }
114410115c80Sfei feng - Sun Microsystems - Beijing China
114510115c80Sfei feng - Sun Microsystems - Beijing China if (r1 & RT2661_RX_DONE) {
114610115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
114710115c80Sfei feng - Sun Microsystems - Beijing China "RT2661_RX_DONE\n");
114810115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_pend = 1;
114910115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_trigger_softint(sc->sc_softintr_hdl, NULL);
115010115c80Sfei feng - Sun Microsystems - Beijing China }
115110115c80Sfei feng - Sun Microsystems - Beijing China
115210115c80Sfei feng - Sun Microsystems - Beijing China if (r1 & RT2661_TX0_DMA_DONE) {
115310115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
115410115c80Sfei feng - Sun Microsystems - Beijing China "RT2661_TX0_DMA_DONE\n");
115510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_tx_dma_intr(sc, &sc->txq[0]);
115610115c80Sfei feng - Sun Microsystems - Beijing China }
115710115c80Sfei feng - Sun Microsystems - Beijing China
115810115c80Sfei feng - Sun Microsystems - Beijing China if (r1 & RT2661_TX1_DMA_DONE) {
115910115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
116010115c80Sfei feng - Sun Microsystems - Beijing China "RT2661_TX1_DMA_DONE\n");
116110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_tx_dma_intr(sc, &sc->txq[1]);
116210115c80Sfei feng - Sun Microsystems - Beijing China }
116310115c80Sfei feng - Sun Microsystems - Beijing China
116410115c80Sfei feng - Sun Microsystems - Beijing China if (r1 & RT2661_TX2_DMA_DONE) {
116510115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
116610115c80Sfei feng - Sun Microsystems - Beijing China "RT2661_TX2_DMA_DONE\n");
116710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_tx_dma_intr(sc, &sc->txq[2]);
116810115c80Sfei feng - Sun Microsystems - Beijing China }
116910115c80Sfei feng - Sun Microsystems - Beijing China
117010115c80Sfei feng - Sun Microsystems - Beijing China if (r1 & RT2661_TX3_DMA_DONE) {
117110115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
117210115c80Sfei feng - Sun Microsystems - Beijing China "RT2661_TX3_DMA_DONE\n");
117310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_tx_dma_intr(sc, &sc->txq[3]);
117410115c80Sfei feng - Sun Microsystems - Beijing China }
117510115c80Sfei feng - Sun Microsystems - Beijing China
117610115c80Sfei feng - Sun Microsystems - Beijing China if (r1 & RT2661_TX_DONE) {
117710115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
117810115c80Sfei feng - Sun Microsystems - Beijing China "RT2661_TX_DONE\n");
117910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_tx_intr(sc);
118010115c80Sfei feng - Sun Microsystems - Beijing China }
118110115c80Sfei feng - Sun Microsystems - Beijing China
118210115c80Sfei feng - Sun Microsystems - Beijing China if (r2 & RT2661_MCU_CMD_DONE) {
118310115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
118410115c80Sfei feng - Sun Microsystems - Beijing China "RT2661_MCU_CMD_DONE\n");
118510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_mcu_cmd_intr(sc);
118610115c80Sfei feng - Sun Microsystems - Beijing China }
118710115c80Sfei feng - Sun Microsystems - Beijing China
118810115c80Sfei feng - Sun Microsystems - Beijing China if (r2 & RT2661_MCU_WAKEUP) {
118910115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
119010115c80Sfei feng - Sun Microsystems - Beijing China "RT2661_MCU_WAKEUP\n");
119110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_mcu_wakeup(sc);
119210115c80Sfei feng - Sun Microsystems - Beijing China }
119310115c80Sfei feng - Sun Microsystems - Beijing China
119410115c80Sfei feng - Sun Microsystems - Beijing China /* re-enable MAC and MCU interrupts */
119510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0x0000ff10);
119610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0);
119710115c80Sfei feng - Sun Microsystems - Beijing China
119810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
119910115c80Sfei feng - Sun Microsystems - Beijing China return (RT2661_SUCCESS);
120010115c80Sfei feng - Sun Microsystems - Beijing China }
120110115c80Sfei feng - Sun Microsystems - Beijing China
120210115c80Sfei feng - Sun Microsystems - Beijing China /*
120310115c80Sfei feng - Sun Microsystems - Beijing China * Retrieve the "Received Signal Strength Indicator" from the raw values
120410115c80Sfei feng - Sun Microsystems - Beijing China * contained in Rx descriptors. The computation depends on which band the
120510115c80Sfei feng - Sun Microsystems - Beijing China * frame was received. Correction values taken from the reference driver.
120610115c80Sfei feng - Sun Microsystems - Beijing China */
120710115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_get_rssi(struct rt2661_softc * sc,uint8_t raw)120810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_get_rssi(struct rt2661_softc *sc, uint8_t raw)
120910115c80Sfei feng - Sun Microsystems - Beijing China {
121010115c80Sfei feng - Sun Microsystems - Beijing China int lna, agc, rssi;
121110115c80Sfei feng - Sun Microsystems - Beijing China
121210115c80Sfei feng - Sun Microsystems - Beijing China lna = (raw >> 5) & 0x3;
121310115c80Sfei feng - Sun Microsystems - Beijing China agc = raw & 0x1f;
121410115c80Sfei feng - Sun Microsystems - Beijing China
121510115c80Sfei feng - Sun Microsystems - Beijing China rssi = 2 * agc;
121610115c80Sfei feng - Sun Microsystems - Beijing China
121710115c80Sfei feng - Sun Microsystems - Beijing China if (IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan)) {
121810115c80Sfei feng - Sun Microsystems - Beijing China rssi += sc->rssi_2ghz_corr;
121910115c80Sfei feng - Sun Microsystems - Beijing China
122010115c80Sfei feng - Sun Microsystems - Beijing China if (lna == 1)
122110115c80Sfei feng - Sun Microsystems - Beijing China rssi -= 64;
122210115c80Sfei feng - Sun Microsystems - Beijing China else if (lna == 2)
122310115c80Sfei feng - Sun Microsystems - Beijing China rssi -= 74;
122410115c80Sfei feng - Sun Microsystems - Beijing China else if (lna == 3)
122510115c80Sfei feng - Sun Microsystems - Beijing China rssi -= 90;
122610115c80Sfei feng - Sun Microsystems - Beijing China } else {
122710115c80Sfei feng - Sun Microsystems - Beijing China rssi += sc->rssi_5ghz_corr;
122810115c80Sfei feng - Sun Microsystems - Beijing China
122910115c80Sfei feng - Sun Microsystems - Beijing China if (lna == 1)
123010115c80Sfei feng - Sun Microsystems - Beijing China rssi -= 64;
123110115c80Sfei feng - Sun Microsystems - Beijing China else if (lna == 2)
123210115c80Sfei feng - Sun Microsystems - Beijing China rssi -= 86;
123310115c80Sfei feng - Sun Microsystems - Beijing China else if (lna == 3)
123410115c80Sfei feng - Sun Microsystems - Beijing China rssi -= 100;
123510115c80Sfei feng - Sun Microsystems - Beijing China }
123610115c80Sfei feng - Sun Microsystems - Beijing China return (rssi);
123710115c80Sfei feng - Sun Microsystems - Beijing China }
123810115c80Sfei feng - Sun Microsystems - Beijing China
123910115c80Sfei feng - Sun Microsystems - Beijing China /* quickly determine if a given rate is CCK or OFDM */
124010115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
124110115c80Sfei feng - Sun Microsystems - Beijing China
124210115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_ACK_SIZE 14 /* 10 + 4(FCS) */
124310115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_CTS_SIZE 14 /* 10 + 4(FCS) */
124410115c80Sfei feng - Sun Microsystems - Beijing China
124510115c80Sfei feng - Sun Microsystems - Beijing China #define RT2661_SIFS 10 /* us */
124610115c80Sfei feng - Sun Microsystems - Beijing China
124710115c80Sfei feng - Sun Microsystems - Beijing China /*
124810115c80Sfei feng - Sun Microsystems - Beijing China * Return the expected ack rate for a frame transmitted at rate `rate'.
124910115c80Sfei feng - Sun Microsystems - Beijing China * XXX: this should depend on the destination node basic rate set.
125010115c80Sfei feng - Sun Microsystems - Beijing China */
125110115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_ack_rate(struct ieee80211com * ic,int rate)125210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_ack_rate(struct ieee80211com *ic, int rate)
125310115c80Sfei feng - Sun Microsystems - Beijing China {
125410115c80Sfei feng - Sun Microsystems - Beijing China switch (rate) {
125510115c80Sfei feng - Sun Microsystems - Beijing China /* CCK rates */
125610115c80Sfei feng - Sun Microsystems - Beijing China case 2:
125710115c80Sfei feng - Sun Microsystems - Beijing China return (2);
125810115c80Sfei feng - Sun Microsystems - Beijing China case 4:
125910115c80Sfei feng - Sun Microsystems - Beijing China case 11:
126010115c80Sfei feng - Sun Microsystems - Beijing China case 22:
126110115c80Sfei feng - Sun Microsystems - Beijing China return ((ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate);
126210115c80Sfei feng - Sun Microsystems - Beijing China
126310115c80Sfei feng - Sun Microsystems - Beijing China /* OFDM rates */
126410115c80Sfei feng - Sun Microsystems - Beijing China case 12:
126510115c80Sfei feng - Sun Microsystems - Beijing China case 18:
126610115c80Sfei feng - Sun Microsystems - Beijing China return (12);
126710115c80Sfei feng - Sun Microsystems - Beijing China case 24:
126810115c80Sfei feng - Sun Microsystems - Beijing China case 36:
126910115c80Sfei feng - Sun Microsystems - Beijing China return (24);
127010115c80Sfei feng - Sun Microsystems - Beijing China case 48:
127110115c80Sfei feng - Sun Microsystems - Beijing China case 72:
127210115c80Sfei feng - Sun Microsystems - Beijing China case 96:
127310115c80Sfei feng - Sun Microsystems - Beijing China case 108:
127410115c80Sfei feng - Sun Microsystems - Beijing China return (48);
127510115c80Sfei feng - Sun Microsystems - Beijing China }
127610115c80Sfei feng - Sun Microsystems - Beijing China
127710115c80Sfei feng - Sun Microsystems - Beijing China /* default to 1Mbps */
127810115c80Sfei feng - Sun Microsystems - Beijing China return (2);
127910115c80Sfei feng - Sun Microsystems - Beijing China }
128010115c80Sfei feng - Sun Microsystems - Beijing China
128110115c80Sfei feng - Sun Microsystems - Beijing China /*
128210115c80Sfei feng - Sun Microsystems - Beijing China * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'.
128310115c80Sfei feng - Sun Microsystems - Beijing China * The function automatically determines the operating mode depending on the
128410115c80Sfei feng - Sun Microsystems - Beijing China * given rate. `flags' indicates whether short preamble is in use or not.
128510115c80Sfei feng - Sun Microsystems - Beijing China */
128610115c80Sfei feng - Sun Microsystems - Beijing China static uint16_t
rt2661_txtime(int len,int rate,uint32_t flags)128710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_txtime(int len, int rate, uint32_t flags)
128810115c80Sfei feng - Sun Microsystems - Beijing China {
128910115c80Sfei feng - Sun Microsystems - Beijing China uint16_t txtime;
129010115c80Sfei feng - Sun Microsystems - Beijing China
129110115c80Sfei feng - Sun Microsystems - Beijing China if (RT2661_RATE_IS_OFDM(rate)) {
129210115c80Sfei feng - Sun Microsystems - Beijing China /* IEEE Std 802.11a-1999, pp. 37 */
129310115c80Sfei feng - Sun Microsystems - Beijing China txtime = (8 + 4 * len + 3 + rate - 1) / rate;
129410115c80Sfei feng - Sun Microsystems - Beijing China txtime = 16 + 4 + 4 * txtime + 6;
129510115c80Sfei feng - Sun Microsystems - Beijing China } else {
129610115c80Sfei feng - Sun Microsystems - Beijing China /* IEEE Std 802.11b-1999, pp. 28 */
129710115c80Sfei feng - Sun Microsystems - Beijing China txtime = (16 * len + rate - 1) / rate;
129810115c80Sfei feng - Sun Microsystems - Beijing China if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE))
129910115c80Sfei feng - Sun Microsystems - Beijing China txtime += 72 + 24;
130010115c80Sfei feng - Sun Microsystems - Beijing China else
130110115c80Sfei feng - Sun Microsystems - Beijing China txtime += 144 + 48;
130210115c80Sfei feng - Sun Microsystems - Beijing China }
130310115c80Sfei feng - Sun Microsystems - Beijing China
130410115c80Sfei feng - Sun Microsystems - Beijing China return (txtime);
130510115c80Sfei feng - Sun Microsystems - Beijing China }
130610115c80Sfei feng - Sun Microsystems - Beijing China
130710115c80Sfei feng - Sun Microsystems - Beijing China static uint8_t
rt2661_plcp_signal(int rate)130810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_plcp_signal(int rate)
130910115c80Sfei feng - Sun Microsystems - Beijing China {
131010115c80Sfei feng - Sun Microsystems - Beijing China switch (rate) {
131110115c80Sfei feng - Sun Microsystems - Beijing China /* CCK rates (returned values are device-dependent) */
131210115c80Sfei feng - Sun Microsystems - Beijing China case 2:
131310115c80Sfei feng - Sun Microsystems - Beijing China return (0x0);
131410115c80Sfei feng - Sun Microsystems - Beijing China case 4:
131510115c80Sfei feng - Sun Microsystems - Beijing China return (0x1);
131610115c80Sfei feng - Sun Microsystems - Beijing China case 11:
131710115c80Sfei feng - Sun Microsystems - Beijing China return (0x2);
131810115c80Sfei feng - Sun Microsystems - Beijing China case 22:
131910115c80Sfei feng - Sun Microsystems - Beijing China return (0x3);
132010115c80Sfei feng - Sun Microsystems - Beijing China
132110115c80Sfei feng - Sun Microsystems - Beijing China /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
132210115c80Sfei feng - Sun Microsystems - Beijing China case 12:
132310115c80Sfei feng - Sun Microsystems - Beijing China return (0xb);
132410115c80Sfei feng - Sun Microsystems - Beijing China case 18:
132510115c80Sfei feng - Sun Microsystems - Beijing China return (0xf);
132610115c80Sfei feng - Sun Microsystems - Beijing China case 24:
132710115c80Sfei feng - Sun Microsystems - Beijing China return (0xa);
132810115c80Sfei feng - Sun Microsystems - Beijing China case 36:
132910115c80Sfei feng - Sun Microsystems - Beijing China return (0xe);
133010115c80Sfei feng - Sun Microsystems - Beijing China case 48:
133110115c80Sfei feng - Sun Microsystems - Beijing China return (0x9);
133210115c80Sfei feng - Sun Microsystems - Beijing China case 72:
133310115c80Sfei feng - Sun Microsystems - Beijing China return (0xd);
133410115c80Sfei feng - Sun Microsystems - Beijing China case 96:
133510115c80Sfei feng - Sun Microsystems - Beijing China return (0x8);
133610115c80Sfei feng - Sun Microsystems - Beijing China case 108:
133710115c80Sfei feng - Sun Microsystems - Beijing China return (0xc);
133810115c80Sfei feng - Sun Microsystems - Beijing China
133910115c80Sfei feng - Sun Microsystems - Beijing China /* unsupported rates (should not get there) */
134010115c80Sfei feng - Sun Microsystems - Beijing China default:
134110115c80Sfei feng - Sun Microsystems - Beijing China return (0xff);
134210115c80Sfei feng - Sun Microsystems - Beijing China }
134310115c80Sfei feng - Sun Microsystems - Beijing China }
134410115c80Sfei feng - Sun Microsystems - Beijing China
134510115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_setup_tx_desc(struct rt2661_softc * sc,struct rt2661_tx_desc * desc,uint32_t flags,uint16_t xflags,int len,int rate,int ac)134610115c80Sfei feng - Sun Microsystems - Beijing China rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc,
134710115c80Sfei feng - Sun Microsystems - Beijing China uint32_t flags, uint16_t xflags, int len, int rate, int ac)
134810115c80Sfei feng - Sun Microsystems - Beijing China {
134910115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
135010115c80Sfei feng - Sun Microsystems - Beijing China uint16_t plcp_length;
135110115c80Sfei feng - Sun Microsystems - Beijing China int remainder;
135210115c80Sfei feng - Sun Microsystems - Beijing China
135310115c80Sfei feng - Sun Microsystems - Beijing China desc->flags = LE_32(flags);
135410115c80Sfei feng - Sun Microsystems - Beijing China desc->flags |= LE_32(len << 16);
135510115c80Sfei feng - Sun Microsystems - Beijing China desc->flags |= LE_32(RT2661_TX_BUSY | RT2661_TX_VALID);
135610115c80Sfei feng - Sun Microsystems - Beijing China
135710115c80Sfei feng - Sun Microsystems - Beijing China desc->xflags = LE_16(xflags);
135810115c80Sfei feng - Sun Microsystems - Beijing China desc->xflags |= LE_16(1 << 13);
135910115c80Sfei feng - Sun Microsystems - Beijing China
136010115c80Sfei feng - Sun Microsystems - Beijing China desc->wme = LE_16(
136110115c80Sfei feng - Sun Microsystems - Beijing China RT2661_QID(ac) |
136210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_AIFSN(2) |
136310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_LOGCWMIN(4) |
136410115c80Sfei feng - Sun Microsystems - Beijing China RT2661_LOGCWMAX(10));
136510115c80Sfei feng - Sun Microsystems - Beijing China
136610115c80Sfei feng - Sun Microsystems - Beijing China /*
136710115c80Sfei feng - Sun Microsystems - Beijing China * Remember in which queue this frame was sent. This field is driver
136810115c80Sfei feng - Sun Microsystems - Beijing China * private data only. It will be made available by the NIC in STA_CSR4
136910115c80Sfei feng - Sun Microsystems - Beijing China * on Tx interrupts.
137010115c80Sfei feng - Sun Microsystems - Beijing China */
137110115c80Sfei feng - Sun Microsystems - Beijing China desc->qid = (uint8_t)ac;
137210115c80Sfei feng - Sun Microsystems - Beijing China
137310115c80Sfei feng - Sun Microsystems - Beijing China /* setup PLCP fields */
137410115c80Sfei feng - Sun Microsystems - Beijing China desc->plcp_signal = rt2661_plcp_signal(rate);
137510115c80Sfei feng - Sun Microsystems - Beijing China desc->plcp_service = 4;
137610115c80Sfei feng - Sun Microsystems - Beijing China
137710115c80Sfei feng - Sun Microsystems - Beijing China len += IEEE80211_CRC_LEN;
137810115c80Sfei feng - Sun Microsystems - Beijing China
137910115c80Sfei feng - Sun Microsystems - Beijing China if (RT2661_RATE_IS_OFDM(rate)) {
138010115c80Sfei feng - Sun Microsystems - Beijing China desc->flags |= LE_32(RT2661_TX_OFDM);
138110115c80Sfei feng - Sun Microsystems - Beijing China
138210115c80Sfei feng - Sun Microsystems - Beijing China plcp_length = len & 0xfff;
138310115c80Sfei feng - Sun Microsystems - Beijing China desc->plcp_length_hi = plcp_length >> 6;
138410115c80Sfei feng - Sun Microsystems - Beijing China desc->plcp_length_lo = plcp_length & 0x3f;
138510115c80Sfei feng - Sun Microsystems - Beijing China } else {
138610115c80Sfei feng - Sun Microsystems - Beijing China plcp_length = (16 * len + rate - 1) / rate;
138710115c80Sfei feng - Sun Microsystems - Beijing China if (rate == 22) {
138810115c80Sfei feng - Sun Microsystems - Beijing China remainder = (16 * len) % 22;
138910115c80Sfei feng - Sun Microsystems - Beijing China if (remainder != 0 && remainder < 7)
139010115c80Sfei feng - Sun Microsystems - Beijing China desc->plcp_service |= RT2661_PLCP_LENGEXT;
139110115c80Sfei feng - Sun Microsystems - Beijing China }
139210115c80Sfei feng - Sun Microsystems - Beijing China desc->plcp_length_hi = plcp_length >> 8;
139310115c80Sfei feng - Sun Microsystems - Beijing China desc->plcp_length_lo = plcp_length & 0xff;
139410115c80Sfei feng - Sun Microsystems - Beijing China
139510115c80Sfei feng - Sun Microsystems - Beijing China if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
139610115c80Sfei feng - Sun Microsystems - Beijing China desc->plcp_signal |= 0x08;
139710115c80Sfei feng - Sun Microsystems - Beijing China }
139810115c80Sfei feng - Sun Microsystems - Beijing China
139910115c80Sfei feng - Sun Microsystems - Beijing China /* RT2x61 supports scatter with up to 5 segments */
140010115c80Sfei feng - Sun Microsystems - Beijing China desc->len [0] = LE_16(len);
140110115c80Sfei feng - Sun Microsystems - Beijing China }
140210115c80Sfei feng - Sun Microsystems - Beijing China
140310115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_send(ieee80211com_t * ic,mblk_t * mp)140410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_send(ieee80211com_t *ic, mblk_t *mp)
140510115c80Sfei feng - Sun Microsystems - Beijing China {
140610115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)ic;
140710115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_ring *ring;
140810115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_desc *desc;
140910115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_data *data;
141010115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211_frame *wh;
141110115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni;
141210115c80Sfei feng - Sun Microsystems - Beijing China
141310115c80Sfei feng - Sun Microsystems - Beijing China int err, off, rate;
141410115c80Sfei feng - Sun Microsystems - Beijing China int mblen, pktlen;
141510115c80Sfei feng - Sun Microsystems - Beijing China mblk_t *m, *m0;
141610115c80Sfei feng - Sun Microsystems - Beijing China uint16_t dur;
141710115c80Sfei feng - Sun Microsystems - Beijing China uint32_t flags = 0;
141810115c80Sfei feng - Sun Microsystems - Beijing China
141910115c80Sfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_txlock);
142010115c80Sfei feng - Sun Microsystems - Beijing China ring = &sc->txq[0];
142110115c80Sfei feng - Sun Microsystems - Beijing China err = DDI_SUCCESS;
142210115c80Sfei feng - Sun Microsystems - Beijing China
142310115c80Sfei feng - Sun Microsystems - Beijing China if (ring->queued > RT2661_TX_RING_COUNT - 8) {
142410115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_need_sched = 1;
142510115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_nobuf++;
142610115c80Sfei feng - Sun Microsystems - Beijing China err = ENOMEM;
142710115c80Sfei feng - Sun Microsystems - Beijing China goto fail1;
142810115c80Sfei feng - Sun Microsystems - Beijing China }
142910115c80Sfei feng - Sun Microsystems - Beijing China
143010115c80Sfei feng - Sun Microsystems - Beijing China m = allocb(msgdsize(mp) + 32, BPRI_MED);
143110115c80Sfei feng - Sun Microsystems - Beijing China if (m == NULL) {
143210115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_send():"
143310115c80Sfei feng - Sun Microsystems - Beijing China "can't alloc mblk.\n");
143410115c80Sfei feng - Sun Microsystems - Beijing China err = DDI_FAILURE;
143510115c80Sfei feng - Sun Microsystems - Beijing China goto fail1;
143610115c80Sfei feng - Sun Microsystems - Beijing China }
143710115c80Sfei feng - Sun Microsystems - Beijing China
143810115c80Sfei feng - Sun Microsystems - Beijing China for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) {
143910115c80Sfei feng - Sun Microsystems - Beijing China mblen = MBLKL(m0);
144010115c80Sfei feng - Sun Microsystems - Beijing China (void) bcopy(m0->b_rptr, m->b_rptr + off, mblen);
144110115c80Sfei feng - Sun Microsystems - Beijing China off += mblen;
144210115c80Sfei feng - Sun Microsystems - Beijing China }
144310115c80Sfei feng - Sun Microsystems - Beijing China m->b_wptr += off;
144410115c80Sfei feng - Sun Microsystems - Beijing China
144510115c80Sfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr;
144610115c80Sfei feng - Sun Microsystems - Beijing China ni = ieee80211_find_txnode(ic, wh->i_addr1);
144710115c80Sfei feng - Sun Microsystems - Beijing China if (ni == NULL) {
144810115c80Sfei feng - Sun Microsystems - Beijing China err = DDI_FAILURE;
144910115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_err++;
145010115c80Sfei feng - Sun Microsystems - Beijing China goto fail2;
145110115c80Sfei feng - Sun Microsystems - Beijing China }
145210115c80Sfei feng - Sun Microsystems - Beijing China
145310115c80Sfei feng - Sun Microsystems - Beijing China (void) ieee80211_encap(ic, m, ni);
145410115c80Sfei feng - Sun Microsystems - Beijing China
145510115c80Sfei feng - Sun Microsystems - Beijing China if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
145610115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211_key *k;
145710115c80Sfei feng - Sun Microsystems - Beijing China k = ieee80211_crypto_encap(ic, m);
145810115c80Sfei feng - Sun Microsystems - Beijing China if (k == NULL) {
145910115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_err++;
146010115c80Sfei feng - Sun Microsystems - Beijing China err = DDI_FAILURE;
146110115c80Sfei feng - Sun Microsystems - Beijing China goto fail3;
146210115c80Sfei feng - Sun Microsystems - Beijing China }
146310115c80Sfei feng - Sun Microsystems - Beijing China /* packet header may have moved, reset our local pointer */
146410115c80Sfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr;
146510115c80Sfei feng - Sun Microsystems - Beijing China }
146610115c80Sfei feng - Sun Microsystems - Beijing China
146710115c80Sfei feng - Sun Microsystems - Beijing China pktlen = msgdsize(m);
146810115c80Sfei feng - Sun Microsystems - Beijing China
146910115c80Sfei feng - Sun Microsystems - Beijing China desc = &ring->desc[ring->cur];
147010115c80Sfei feng - Sun Microsystems - Beijing China data = &ring->data[ring->cur];
147110115c80Sfei feng - Sun Microsystems - Beijing China data->ni = ieee80211_ref_node(ni);
147210115c80Sfei feng - Sun Microsystems - Beijing China
147310115c80Sfei feng - Sun Microsystems - Beijing China /* pickup a rate */
147410115c80Sfei feng - Sun Microsystems - Beijing China if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
147510115c80Sfei feng - Sun Microsystems - Beijing China /* multicast frames are sent at the lowest avail. rate */
147610115c80Sfei feng - Sun Microsystems - Beijing China rate = ni->in_rates.ir_rates[0];
147710115c80Sfei feng - Sun Microsystems - Beijing China } else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) {
147810115c80Sfei feng - Sun Microsystems - Beijing China rate = ic->ic_sup_rates[ic->ic_curmode].
147910115c80Sfei feng - Sun Microsystems - Beijing China ir_rates[ic->ic_fixed_rate];
148010115c80Sfei feng - Sun Microsystems - Beijing China } else
148110115c80Sfei feng - Sun Microsystems - Beijing China rate = ni->in_rates.ir_rates[ni->in_txrate];
148210115c80Sfei feng - Sun Microsystems - Beijing China if (rate == 0)
148310115c80Sfei feng - Sun Microsystems - Beijing China rate = 2; /* XXX should not happen */
148410115c80Sfei feng - Sun Microsystems - Beijing China rate &= IEEE80211_RATE_VAL;
148510115c80Sfei feng - Sun Microsystems - Beijing China
148610115c80Sfei feng - Sun Microsystems - Beijing China if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
148710115c80Sfei feng - Sun Microsystems - Beijing China flags |= RT2661_TX_NEED_ACK;
148810115c80Sfei feng - Sun Microsystems - Beijing China
148910115c80Sfei feng - Sun Microsystems - Beijing China dur = rt2661_txtime(RT2661_ACK_SIZE,
149010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_ack_rate(ic, rate), ic->ic_flags) + sc->sifs;
149110115c80Sfei feng - Sun Microsystems - Beijing China *(uint16_t *)wh->i_dur = LE_16(dur);
149210115c80Sfei feng - Sun Microsystems - Beijing China }
149310115c80Sfei feng - Sun Microsystems - Beijing China
149410115c80Sfei feng - Sun Microsystems - Beijing China bcopy(m->b_rptr, data->buf, pktlen);
149510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_setup_tx_desc(sc, desc, flags, 0, pktlen, rate, 0);
149610115c80Sfei feng - Sun Microsystems - Beijing China
149710115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(data->txdata_dma.dma_hdl,
149810115c80Sfei feng - Sun Microsystems - Beijing China 0, pktlen,
149910115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV);
150010115c80Sfei feng - Sun Microsystems - Beijing China
150110115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
150210115c80Sfei feng - Sun Microsystems - Beijing China ring->cur * RT2661_TX_DESC_SIZE,
150310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_TX_DESC_SIZE,
150410115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV);
150510115c80Sfei feng - Sun Microsystems - Beijing China
150610115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_send(): "
150710115c80Sfei feng - Sun Microsystems - Beijing China "sending data frame len=%u idx=%u rate=%u\n",
150810115c80Sfei feng - Sun Microsystems - Beijing China pktlen, ring->cur, rate);
150910115c80Sfei feng - Sun Microsystems - Beijing China
151010115c80Sfei feng - Sun Microsystems - Beijing China /* kick Tx */
151110115c80Sfei feng - Sun Microsystems - Beijing China ring->queued++;
151210115c80Sfei feng - Sun Microsystems - Beijing China ring->cur = (ring->cur + 1) % RT2661_TX_RING_COUNT;
151310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TX_CNTL_CSR, 1 << 0);
151410115c80Sfei feng - Sun Microsystems - Beijing China
151510115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_stats.is_tx_frags++;
151610115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_stats.is_tx_bytes += pktlen;
151710115c80Sfei feng - Sun Microsystems - Beijing China fail3:
151810115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_free_node(ni);
151910115c80Sfei feng - Sun Microsystems - Beijing China fail2:
152010115c80Sfei feng - Sun Microsystems - Beijing China freemsg(m);
152110115c80Sfei feng - Sun Microsystems - Beijing China fail1:
152210115c80Sfei feng - Sun Microsystems - Beijing China if (err == DDI_SUCCESS)
152310115c80Sfei feng - Sun Microsystems - Beijing China freemsg(mp);
152410115c80Sfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_txlock);
152510115c80Sfei feng - Sun Microsystems - Beijing China return (err);
152610115c80Sfei feng - Sun Microsystems - Beijing China }
152710115c80Sfei feng - Sun Microsystems - Beijing China
152810115c80Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/
152910115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_mgmt_send(ieee80211com_t * ic,mblk_t * mp,uint8_t type)153010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_mgmt_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
153110115c80Sfei feng - Sun Microsystems - Beijing China {
153210115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)ic;
153310115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_ring *ring;
153410115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_desc *desc;
153510115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_tx_data *data;
153610115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211_frame *wh;
153710115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni;
153810115c80Sfei feng - Sun Microsystems - Beijing China
153910115c80Sfei feng - Sun Microsystems - Beijing China int err, off, rate;
154010115c80Sfei feng - Sun Microsystems - Beijing China int mblen, pktlen;
154110115c80Sfei feng - Sun Microsystems - Beijing China mblk_t *m, *m0;
154210115c80Sfei feng - Sun Microsystems - Beijing China uint16_t dur;
154310115c80Sfei feng - Sun Microsystems - Beijing China uint32_t flags = 0;
154410115c80Sfei feng - Sun Microsystems - Beijing China
154510115c80Sfei feng - Sun Microsystems - Beijing China if ((!RT2661_IS_RUNNING(sc)) || RT2661_IS_SUSPEND(sc)) {
154610115c80Sfei feng - Sun Microsystems - Beijing China err = ENXIO;
154710115c80Sfei feng - Sun Microsystems - Beijing China goto fail1;
154810115c80Sfei feng - Sun Microsystems - Beijing China }
154910115c80Sfei feng - Sun Microsystems - Beijing China
155010115c80Sfei feng - Sun Microsystems - Beijing China ring = &sc->mgtq;
155110115c80Sfei feng - Sun Microsystems - Beijing China err = DDI_SUCCESS;
155210115c80Sfei feng - Sun Microsystems - Beijing China
155310115c80Sfei feng - Sun Microsystems - Beijing China if (ring->queued >= RT2661_MGT_RING_COUNT) {
155410115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_nobuf++;
155510115c80Sfei feng - Sun Microsystems - Beijing China err = ENOMEM;
155610115c80Sfei feng - Sun Microsystems - Beijing China goto fail1;
155710115c80Sfei feng - Sun Microsystems - Beijing China }
155810115c80Sfei feng - Sun Microsystems - Beijing China
155910115c80Sfei feng - Sun Microsystems - Beijing China m = allocb(msgdsize(mp) + 32, BPRI_MED);
156010115c80Sfei feng - Sun Microsystems - Beijing China if (m == NULL) {
156110115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_mgmt_send():"
156210115c80Sfei feng - Sun Microsystems - Beijing China "can't alloc mblk.\n");
156310115c80Sfei feng - Sun Microsystems - Beijing China err = DDI_FAILURE;
156410115c80Sfei feng - Sun Microsystems - Beijing China goto fail1;
156510115c80Sfei feng - Sun Microsystems - Beijing China }
156610115c80Sfei feng - Sun Microsystems - Beijing China
156710115c80Sfei feng - Sun Microsystems - Beijing China for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) {
156810115c80Sfei feng - Sun Microsystems - Beijing China mblen = MBLKL(m0);
156910115c80Sfei feng - Sun Microsystems - Beijing China (void) bcopy(m0->b_rptr, m->b_rptr + off, mblen);
157010115c80Sfei feng - Sun Microsystems - Beijing China off += mblen;
157110115c80Sfei feng - Sun Microsystems - Beijing China }
157210115c80Sfei feng - Sun Microsystems - Beijing China m->b_wptr += off;
157310115c80Sfei feng - Sun Microsystems - Beijing China
157410115c80Sfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr;
157510115c80Sfei feng - Sun Microsystems - Beijing China ni = ieee80211_find_txnode(ic, wh->i_addr1);
157610115c80Sfei feng - Sun Microsystems - Beijing China if (ni == NULL) {
157710115c80Sfei feng - Sun Microsystems - Beijing China err = DDI_FAILURE;
157810115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_err++;
157910115c80Sfei feng - Sun Microsystems - Beijing China goto fail2;
158010115c80Sfei feng - Sun Microsystems - Beijing China }
158110115c80Sfei feng - Sun Microsystems - Beijing China
158210115c80Sfei feng - Sun Microsystems - Beijing China if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
158310115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211_key *k;
158410115c80Sfei feng - Sun Microsystems - Beijing China k = ieee80211_crypto_encap(ic, m);
158510115c80Sfei feng - Sun Microsystems - Beijing China if (k == NULL) {
158610115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_err++;
158710115c80Sfei feng - Sun Microsystems - Beijing China err = DDI_FAILURE;
158810115c80Sfei feng - Sun Microsystems - Beijing China goto fail3;
158910115c80Sfei feng - Sun Microsystems - Beijing China }
159010115c80Sfei feng - Sun Microsystems - Beijing China /* packet header may have moved, reset our local pointer */
159110115c80Sfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr;
159210115c80Sfei feng - Sun Microsystems - Beijing China }
159310115c80Sfei feng - Sun Microsystems - Beijing China
159410115c80Sfei feng - Sun Microsystems - Beijing China pktlen = msgdsize(m);
159510115c80Sfei feng - Sun Microsystems - Beijing China
159610115c80Sfei feng - Sun Microsystems - Beijing China desc = &ring->desc[ring->cur];
159710115c80Sfei feng - Sun Microsystems - Beijing China data = &ring->data[ring->cur];
159810115c80Sfei feng - Sun Microsystems - Beijing China data->ni = ieee80211_ref_node(ni);
159910115c80Sfei feng - Sun Microsystems - Beijing China
160010115c80Sfei feng - Sun Microsystems - Beijing China /* send mgt frames at the lowest available rate */
160110115c80Sfei feng - Sun Microsystems - Beijing China rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
160210115c80Sfei feng - Sun Microsystems - Beijing China
160310115c80Sfei feng - Sun Microsystems - Beijing China if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
160410115c80Sfei feng - Sun Microsystems - Beijing China flags |= RT2661_TX_NEED_ACK;
160510115c80Sfei feng - Sun Microsystems - Beijing China
160610115c80Sfei feng - Sun Microsystems - Beijing China dur = rt2661_txtime(RT2661_ACK_SIZE,
160710115c80Sfei feng - Sun Microsystems - Beijing China rate, ic->ic_flags) + sc->sifs;
160810115c80Sfei feng - Sun Microsystems - Beijing China *(uint16_t *)wh->i_dur = LE_16(dur);
160910115c80Sfei feng - Sun Microsystems - Beijing China
161010115c80Sfei feng - Sun Microsystems - Beijing China /* tell hardware to add timestamp in probe responses */
161110115c80Sfei feng - Sun Microsystems - Beijing China if ((wh->i_fc[0] &
161210115c80Sfei feng - Sun Microsystems - Beijing China (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
161310115c80Sfei feng - Sun Microsystems - Beijing China (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
161410115c80Sfei feng - Sun Microsystems - Beijing China flags |= RT2661_TX_TIMESTAMP;
161510115c80Sfei feng - Sun Microsystems - Beijing China }
161610115c80Sfei feng - Sun Microsystems - Beijing China
161710115c80Sfei feng - Sun Microsystems - Beijing China bcopy(m->b_rptr, data->buf, pktlen);
161810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_setup_tx_desc(sc, desc, flags, 0, pktlen, rate, RT2661_QID_MGT);
161910115c80Sfei feng - Sun Microsystems - Beijing China
162010115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(data->txdata_dma.dma_hdl,
162110115c80Sfei feng - Sun Microsystems - Beijing China 0, pktlen,
162210115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV);
162310115c80Sfei feng - Sun Microsystems - Beijing China
162410115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
162510115c80Sfei feng - Sun Microsystems - Beijing China ring->cur * RT2661_TX_DESC_SIZE,
162610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_TX_DESC_SIZE,
162710115c80Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV);
162810115c80Sfei feng - Sun Microsystems - Beijing China
162910115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_mgmt_send(): "
163010115c80Sfei feng - Sun Microsystems - Beijing China "sending mgmt frame len=%u idx=%u rate=%u\n",
163110115c80Sfei feng - Sun Microsystems - Beijing China pktlen, ring->cur, rate);
163210115c80Sfei feng - Sun Microsystems - Beijing China
163310115c80Sfei feng - Sun Microsystems - Beijing China /* kick Tx */
163410115c80Sfei feng - Sun Microsystems - Beijing China ring->queued++;
163510115c80Sfei feng - Sun Microsystems - Beijing China ring->cur = (ring->cur + 1) % RT2661_MGT_RING_COUNT;
163610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TX_CNTL_CSR, RT2661_KICK_MGT);
163710115c80Sfei feng - Sun Microsystems - Beijing China
163810115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_stats.is_tx_frags++;
163910115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_stats.is_tx_bytes += pktlen;
164010115c80Sfei feng - Sun Microsystems - Beijing China
164110115c80Sfei feng - Sun Microsystems - Beijing China fail3:
164210115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_free_node(ni);
164310115c80Sfei feng - Sun Microsystems - Beijing China fail2:
164410115c80Sfei feng - Sun Microsystems - Beijing China freemsg(m);
164510115c80Sfei feng - Sun Microsystems - Beijing China fail1:
164610115c80Sfei feng - Sun Microsystems - Beijing China freemsg(mp);
164710115c80Sfei feng - Sun Microsystems - Beijing China return (err);
164810115c80Sfei feng - Sun Microsystems - Beijing China }
164910115c80Sfei feng - Sun Microsystems - Beijing China
165010115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_amrr_node_init(const struct rt2661_amrr * amrr,struct rt2661_amrr_node * amn)165110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_amrr_node_init(const struct rt2661_amrr *amrr,
165210115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_amrr_node *amn)
165310115c80Sfei feng - Sun Microsystems - Beijing China {
165410115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_success = 0;
165510115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_recovery = 0;
165610115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_txcnt = amn->amn_retrycnt = 0;
165710115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_success_threshold = amrr->amrr_min_success_threshold;
165810115c80Sfei feng - Sun Microsystems - Beijing China }
165910115c80Sfei feng - Sun Microsystems - Beijing China
166010115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_amrr_choose(struct rt2661_amrr * amrr,struct ieee80211_node * ni,struct rt2661_amrr_node * amn)166110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_amrr_choose(struct rt2661_amrr *amrr, struct ieee80211_node *ni,
166210115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_amrr_node *amn)
166310115c80Sfei feng - Sun Microsystems - Beijing China {
166410115c80Sfei feng - Sun Microsystems - Beijing China #define RV(rate) ((rate) & IEEE80211_RATE_VAL)
166510115c80Sfei feng - Sun Microsystems - Beijing China #define is_success(amn) \
166610115c80Sfei feng - Sun Microsystems - Beijing China ((amn)->amn_retrycnt < (amn)->amn_txcnt / 10)
166710115c80Sfei feng - Sun Microsystems - Beijing China #define is_failure(amn) \
166810115c80Sfei feng - Sun Microsystems - Beijing China ((amn)->amn_retrycnt > (amn)->amn_txcnt / 3)
166910115c80Sfei feng - Sun Microsystems - Beijing China #define is_enough(amn) \
167010115c80Sfei feng - Sun Microsystems - Beijing China ((amn)->amn_txcnt > 10)
167110115c80Sfei feng - Sun Microsystems - Beijing China #define is_min_rate(ni) \
167210115c80Sfei feng - Sun Microsystems - Beijing China ((ni)->in_txrate == 0)
167310115c80Sfei feng - Sun Microsystems - Beijing China #define is_max_rate(ni) \
167410115c80Sfei feng - Sun Microsystems - Beijing China ((ni)->in_txrate == (ni)->in_rates.ir_nrates - 1)
167510115c80Sfei feng - Sun Microsystems - Beijing China #define increase_rate(ni) \
167610115c80Sfei feng - Sun Microsystems - Beijing China ((ni)->in_txrate++)
167710115c80Sfei feng - Sun Microsystems - Beijing China #define decrease_rate(ni) \
167810115c80Sfei feng - Sun Microsystems - Beijing China ((ni)->in_txrate--)
167910115c80Sfei feng - Sun Microsystems - Beijing China #define reset_cnt(amn) \
168010115c80Sfei feng - Sun Microsystems - Beijing China { (amn)->amn_txcnt = (amn)->amn_retrycnt = 0; }
168110115c80Sfei feng - Sun Microsystems - Beijing China
168210115c80Sfei feng - Sun Microsystems - Beijing China int need_change = 0;
168310115c80Sfei feng - Sun Microsystems - Beijing China
168410115c80Sfei feng - Sun Microsystems - Beijing China if (is_success(amn) && is_enough(amn)) {
168510115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_success++;
168610115c80Sfei feng - Sun Microsystems - Beijing China if (amn->amn_success >= amn->amn_success_threshold &&
168710115c80Sfei feng - Sun Microsystems - Beijing China !is_max_rate(ni)) {
168810115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_recovery = 1;
168910115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_success = 0;
169010115c80Sfei feng - Sun Microsystems - Beijing China increase_rate(ni);
169110115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_amrr_choose(): "
169210115c80Sfei feng - Sun Microsystems - Beijing China "increase rate = %d, #tx = %d, #retries = %d\n",
169310115c80Sfei feng - Sun Microsystems - Beijing China RV(ni->in_rates.ir_rates[ni->in_txrate]),
169410115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_txcnt, amn->amn_retrycnt);
169510115c80Sfei feng - Sun Microsystems - Beijing China need_change = 1;
169610115c80Sfei feng - Sun Microsystems - Beijing China } else
169710115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_recovery = 0;
169810115c80Sfei feng - Sun Microsystems - Beijing China } else if (is_failure(amn)) {
169910115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_success = 0;
170010115c80Sfei feng - Sun Microsystems - Beijing China if (!is_min_rate(ni)) {
170110115c80Sfei feng - Sun Microsystems - Beijing China if (amn->amn_recovery) {
170210115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_success_threshold *= 2;
170310115c80Sfei feng - Sun Microsystems - Beijing China if (amn->amn_success_threshold >
170410115c80Sfei feng - Sun Microsystems - Beijing China amrr->amrr_max_success_threshold)
170510115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_success_threshold =
170610115c80Sfei feng - Sun Microsystems - Beijing China amrr->amrr_max_success_threshold;
170710115c80Sfei feng - Sun Microsystems - Beijing China } else {
170810115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_success_threshold =
170910115c80Sfei feng - Sun Microsystems - Beijing China amrr->amrr_min_success_threshold;
171010115c80Sfei feng - Sun Microsystems - Beijing China }
171110115c80Sfei feng - Sun Microsystems - Beijing China decrease_rate(ni);
171210115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_amrr_choose(): "
171310115c80Sfei feng - Sun Microsystems - Beijing China "decrease rate = %d, #tx = %d, #retries = %d\n",
171410115c80Sfei feng - Sun Microsystems - Beijing China RV(ni->in_rates.ir_rates[ni->in_txrate]),
171510115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_txcnt, amn->amn_retrycnt);
171610115c80Sfei feng - Sun Microsystems - Beijing China need_change = 1;
171710115c80Sfei feng - Sun Microsystems - Beijing China }
171810115c80Sfei feng - Sun Microsystems - Beijing China amn->amn_recovery = 0;
171910115c80Sfei feng - Sun Microsystems - Beijing China }
172010115c80Sfei feng - Sun Microsystems - Beijing China
172110115c80Sfei feng - Sun Microsystems - Beijing China if (is_enough(amn) || need_change)
172210115c80Sfei feng - Sun Microsystems - Beijing China reset_cnt(amn);
172310115c80Sfei feng - Sun Microsystems - Beijing China #undef RV
172410115c80Sfei feng - Sun Microsystems - Beijing China
172510115c80Sfei feng - Sun Microsystems - Beijing China }
172610115c80Sfei feng - Sun Microsystems - Beijing China
172710115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_update_promisc(struct rt2661_softc * sc)172810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_update_promisc(struct rt2661_softc *sc)
172910115c80Sfei feng - Sun Microsystems - Beijing China {
173010115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
173110115c80Sfei feng - Sun Microsystems - Beijing China
173210115c80Sfei feng - Sun Microsystems - Beijing China tmp = RT2661_READ(sc, RT2661_TXRX_CSR0);
173310115c80Sfei feng - Sun Microsystems - Beijing China
173410115c80Sfei feng - Sun Microsystems - Beijing China tmp &= ~RT2661_DROP_NOT_TO_ME;
173510115c80Sfei feng - Sun Microsystems - Beijing China if (!(sc->sc_rcr & RT2661_RCR_PROMISC))
173610115c80Sfei feng - Sun Microsystems - Beijing China tmp |= RT2661_DROP_NOT_TO_ME;
173710115c80Sfei feng - Sun Microsystems - Beijing China
173810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp);
173910115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_update_promisc(): "
174010115c80Sfei feng - Sun Microsystems - Beijing China "%s promiscuous mode\n",
174110115c80Sfei feng - Sun Microsystems - Beijing China (sc->sc_rcr & RT2661_RCR_PROMISC) ? "entering" : "leaving");
174210115c80Sfei feng - Sun Microsystems - Beijing China }
174310115c80Sfei feng - Sun Microsystems - Beijing China
174410115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_updateslot(struct ieee80211com * ic,int onoff)174510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_updateslot(struct ieee80211com *ic, int onoff)
174610115c80Sfei feng - Sun Microsystems - Beijing China {
174710115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)ic;
174810115c80Sfei feng - Sun Microsystems - Beijing China uint8_t slottime;
174910115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
175010115c80Sfei feng - Sun Microsystems - Beijing China
175110115c80Sfei feng - Sun Microsystems - Beijing China slottime = (onoff ? 9 : 20);
175210115c80Sfei feng - Sun Microsystems - Beijing China
175310115c80Sfei feng - Sun Microsystems - Beijing China tmp = RT2661_READ(sc, RT2661_MAC_CSR9);
175410115c80Sfei feng - Sun Microsystems - Beijing China tmp = (tmp & ~0xff) | slottime;
175510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MAC_CSR9, tmp);
175610115c80Sfei feng - Sun Microsystems - Beijing China
175710115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_updateslot(): "
175810115c80Sfei feng - Sun Microsystems - Beijing China "setting slot time to %uus\n", slottime);
175910115c80Sfei feng - Sun Microsystems - Beijing China }
176010115c80Sfei feng - Sun Microsystems - Beijing China
176110115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_set_slottime(struct rt2661_softc * sc)176210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_slottime(struct rt2661_softc *sc)
176310115c80Sfei feng - Sun Microsystems - Beijing China {
176410115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
176510115c80Sfei feng - Sun Microsystems - Beijing China uint8_t slottime;
176610115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
176710115c80Sfei feng - Sun Microsystems - Beijing China
176810115c80Sfei feng - Sun Microsystems - Beijing China slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
176910115c80Sfei feng - Sun Microsystems - Beijing China
177010115c80Sfei feng - Sun Microsystems - Beijing China tmp = RT2661_READ(sc, RT2661_MAC_CSR9);
177110115c80Sfei feng - Sun Microsystems - Beijing China tmp = (tmp & ~0xff) | slottime;
177210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MAC_CSR9, tmp);
177310115c80Sfei feng - Sun Microsystems - Beijing China
177410115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_set_slottime(): "
177510115c80Sfei feng - Sun Microsystems - Beijing China "setting slot time to %uus\n", slottime);
177610115c80Sfei feng - Sun Microsystems - Beijing China }
177710115c80Sfei feng - Sun Microsystems - Beijing China
177810115c80Sfei feng - Sun Microsystems - Beijing China
177910115c80Sfei feng - Sun Microsystems - Beijing China /*
178010115c80Sfei feng - Sun Microsystems - Beijing China * Enable multi-rate retries for frames sent at OFDM rates.
178110115c80Sfei feng - Sun Microsystems - Beijing China * In 802.11b/g mode, allow fallback to CCK rates.
178210115c80Sfei feng - Sun Microsystems - Beijing China */
178310115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_enable_mrr(struct rt2661_softc * sc)178410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_enable_mrr(struct rt2661_softc *sc)
178510115c80Sfei feng - Sun Microsystems - Beijing China {
178610115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
178710115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
178810115c80Sfei feng - Sun Microsystems - Beijing China
178910115c80Sfei feng - Sun Microsystems - Beijing China tmp = RT2661_READ(sc, RT2661_TXRX_CSR4);
179010115c80Sfei feng - Sun Microsystems - Beijing China
179110115c80Sfei feng - Sun Microsystems - Beijing China tmp &= ~RT2661_MRR_CCK_FALLBACK;
179210115c80Sfei feng - Sun Microsystems - Beijing China if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
179310115c80Sfei feng - Sun Microsystems - Beijing China tmp |= RT2661_MRR_CCK_FALLBACK;
179410115c80Sfei feng - Sun Microsystems - Beijing China tmp |= RT2661_MRR_ENABLED;
179510115c80Sfei feng - Sun Microsystems - Beijing China
179610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TXRX_CSR4, tmp);
179710115c80Sfei feng - Sun Microsystems - Beijing China }
179810115c80Sfei feng - Sun Microsystems - Beijing China
179910115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_set_txpreamble(struct rt2661_softc * sc)180010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_txpreamble(struct rt2661_softc *sc)
180110115c80Sfei feng - Sun Microsystems - Beijing China {
180210115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
180310115c80Sfei feng - Sun Microsystems - Beijing China
180410115c80Sfei feng - Sun Microsystems - Beijing China tmp = RT2661_READ(sc, RT2661_TXRX_CSR4);
180510115c80Sfei feng - Sun Microsystems - Beijing China
180610115c80Sfei feng - Sun Microsystems - Beijing China tmp &= ~RT2661_SHORT_PREAMBLE;
180710115c80Sfei feng - Sun Microsystems - Beijing China if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE)
180810115c80Sfei feng - Sun Microsystems - Beijing China tmp |= RT2661_SHORT_PREAMBLE;
180910115c80Sfei feng - Sun Microsystems - Beijing China
181010115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TXRX_CSR4, tmp);
181110115c80Sfei feng - Sun Microsystems - Beijing China }
181210115c80Sfei feng - Sun Microsystems - Beijing China
181310115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_set_basicrates(struct rt2661_softc * sc)181410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_basicrates(struct rt2661_softc *sc)
181510115c80Sfei feng - Sun Microsystems - Beijing China {
181610115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
181710115c80Sfei feng - Sun Microsystems - Beijing China
181810115c80Sfei feng - Sun Microsystems - Beijing China /* update basic rate set */
181910115c80Sfei feng - Sun Microsystems - Beijing China if (ic->ic_curmode == IEEE80211_MODE_11B) {
182010115c80Sfei feng - Sun Microsystems - Beijing China /* 11b basic rates: 1, 2Mbps */
182110115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TXRX_CSR5, 0x3);
182210115c80Sfei feng - Sun Microsystems - Beijing China } else if (ic->ic_curmode == IEEE80211_MODE_11A) {
182310115c80Sfei feng - Sun Microsystems - Beijing China /* 11a basic rates: 6, 12, 24Mbps */
182410115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TXRX_CSR5, 0x150);
182510115c80Sfei feng - Sun Microsystems - Beijing China } else {
182610115c80Sfei feng - Sun Microsystems - Beijing China /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
182710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TXRX_CSR5, 0xf);
182810115c80Sfei feng - Sun Microsystems - Beijing China }
182910115c80Sfei feng - Sun Microsystems - Beijing China }
183010115c80Sfei feng - Sun Microsystems - Beijing China
183110115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_set_bssid(struct rt2661_softc * sc,const uint8_t * bssid)183210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_bssid(struct rt2661_softc *sc, const uint8_t *bssid)
183310115c80Sfei feng - Sun Microsystems - Beijing China {
183410115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
183510115c80Sfei feng - Sun Microsystems - Beijing China
183610115c80Sfei feng - Sun Microsystems - Beijing China tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
183710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MAC_CSR4, tmp);
183810115c80Sfei feng - Sun Microsystems - Beijing China
183910115c80Sfei feng - Sun Microsystems - Beijing China tmp = bssid[4] | bssid[5] << 8 | RT2661_ONE_BSSID << 16;
184010115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MAC_CSR5, tmp);
184110115c80Sfei feng - Sun Microsystems - Beijing China }
184210115c80Sfei feng - Sun Microsystems - Beijing China
184310115c80Sfei feng - Sun Microsystems - Beijing China /*
184410115c80Sfei feng - Sun Microsystems - Beijing China * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
184510115c80Sfei feng - Sun Microsystems - Beijing China * and HostAP operating modes.
184610115c80Sfei feng - Sun Microsystems - Beijing China */
184710115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_enable_tsf_sync(struct rt2661_softc * sc)184810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_enable_tsf_sync(struct rt2661_softc *sc)
184910115c80Sfei feng - Sun Microsystems - Beijing China {
185010115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
185110115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
185210115c80Sfei feng - Sun Microsystems - Beijing China
185310115c80Sfei feng - Sun Microsystems - Beijing China tmp = RT2661_READ(sc, RT2661_TXRX_CSR9) & 0xff000000;
185410115c80Sfei feng - Sun Microsystems - Beijing China
185510115c80Sfei feng - Sun Microsystems - Beijing China /* set beacon interval (in 1/16ms unit) */
185610115c80Sfei feng - Sun Microsystems - Beijing China tmp |= ic->ic_bss->in_intval * 16;
185710115c80Sfei feng - Sun Microsystems - Beijing China
185810115c80Sfei feng - Sun Microsystems - Beijing China tmp |= RT2661_TSF_TICKING | RT2661_ENABLE_TBTT;
185910115c80Sfei feng - Sun Microsystems - Beijing China if (ic->ic_opmode == IEEE80211_M_STA)
186010115c80Sfei feng - Sun Microsystems - Beijing China tmp |= RT2661_TSF_MODE(1);
186110115c80Sfei feng - Sun Microsystems - Beijing China
186210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TXRX_CSR9, tmp);
186310115c80Sfei feng - Sun Microsystems - Beijing China }
186410115c80Sfei feng - Sun Microsystems - Beijing China
186510115c80Sfei feng - Sun Microsystems - Beijing China
186610115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_next_scan(void * arg)186710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_next_scan(void *arg)
186810115c80Sfei feng - Sun Microsystems - Beijing China {
186910115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = arg;
187010115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
187110115c80Sfei feng - Sun Microsystems - Beijing China
187210115c80Sfei feng - Sun Microsystems - Beijing China if (ic->ic_state == IEEE80211_S_SCAN)
187310115c80Sfei feng - Sun Microsystems - Beijing China (void) ieee80211_next_scan(ic);
187410115c80Sfei feng - Sun Microsystems - Beijing China }
187510115c80Sfei feng - Sun Microsystems - Beijing China
187610115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_newassoc(struct ieee80211com * ic,struct ieee80211_node * ni)187710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni)
187810115c80Sfei feng - Sun Microsystems - Beijing China {
187910115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)ic;
188010115c80Sfei feng - Sun Microsystems - Beijing China int i;
188110115c80Sfei feng - Sun Microsystems - Beijing China
188210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_amrr_node_init(&sc->amrr, &((struct rt2661_node *)ni)->amn);
188310115c80Sfei feng - Sun Microsystems - Beijing China
188410115c80Sfei feng - Sun Microsystems - Beijing China /* set rate to some reasonable initial value */
188510115c80Sfei feng - Sun Microsystems - Beijing China i = ni->in_rates.ir_nrates - 1;
188610115c80Sfei feng - Sun Microsystems - Beijing China while (i > 0 && ((ni->in_rates.ir_rates[i] & IEEE80211_RATE_VAL) > 72))
188710115c80Sfei feng - Sun Microsystems - Beijing China i--;
188810115c80Sfei feng - Sun Microsystems - Beijing China
188910115c80Sfei feng - Sun Microsystems - Beijing China ni->in_txrate = i;
189010115c80Sfei feng - Sun Microsystems - Beijing China }
189110115c80Sfei feng - Sun Microsystems - Beijing China
189210115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_iter_func(void * arg,struct ieee80211_node * ni)189310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_iter_func(void *arg, struct ieee80211_node *ni)
189410115c80Sfei feng - Sun Microsystems - Beijing China {
189510115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = arg;
189610115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_node *rn = (struct rt2661_node *)ni;
189710115c80Sfei feng - Sun Microsystems - Beijing China
189810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_amrr_choose(&sc->amrr, ni, &rn->amn);
189910115c80Sfei feng - Sun Microsystems - Beijing China
190010115c80Sfei feng - Sun Microsystems - Beijing China }
190110115c80Sfei feng - Sun Microsystems - Beijing China
190210115c80Sfei feng - Sun Microsystems - Beijing China /*
190310115c80Sfei feng - Sun Microsystems - Beijing China * Dynamically tune Rx sensitivity (BBP register 17) based on average RSSI and
190410115c80Sfei feng - Sun Microsystems - Beijing China * false CCA count. This function is called periodically (every seconds) when
190510115c80Sfei feng - Sun Microsystems - Beijing China * in the RUN state. Values taken from the reference driver.
190610115c80Sfei feng - Sun Microsystems - Beijing China */
190710115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_rx_tune(struct rt2661_softc * sc)190810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rx_tune(struct rt2661_softc *sc)
190910115c80Sfei feng - Sun Microsystems - Beijing China {
191010115c80Sfei feng - Sun Microsystems - Beijing China uint8_t bbp17;
191110115c80Sfei feng - Sun Microsystems - Beijing China uint16_t cca;
191210115c80Sfei feng - Sun Microsystems - Beijing China int lo, hi, dbm;
191310115c80Sfei feng - Sun Microsystems - Beijing China
191410115c80Sfei feng - Sun Microsystems - Beijing China /*
191510115c80Sfei feng - Sun Microsystems - Beijing China * Tuning range depends on operating band and on the presence of an
191610115c80Sfei feng - Sun Microsystems - Beijing China * external low-noise amplifier.
191710115c80Sfei feng - Sun Microsystems - Beijing China */
191810115c80Sfei feng - Sun Microsystems - Beijing China lo = 0x20;
191910115c80Sfei feng - Sun Microsystems - Beijing China if (IEEE80211_IS_CHAN_5GHZ(sc->sc_curchan))
192010115c80Sfei feng - Sun Microsystems - Beijing China lo += 0x08;
192110115c80Sfei feng - Sun Microsystems - Beijing China if ((IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) && sc->ext_2ghz_lna) ||
192210115c80Sfei feng - Sun Microsystems - Beijing China (IEEE80211_IS_CHAN_5GHZ(sc->sc_curchan) && sc->ext_5ghz_lna))
192310115c80Sfei feng - Sun Microsystems - Beijing China lo += 0x10;
192410115c80Sfei feng - Sun Microsystems - Beijing China hi = lo + 0x20;
192510115c80Sfei feng - Sun Microsystems - Beijing China
192610115c80Sfei feng - Sun Microsystems - Beijing China dbm = sc->avg_rssi;
192710115c80Sfei feng - Sun Microsystems - Beijing China /* retrieve false CCA count since last call (clear on read) */
192810115c80Sfei feng - Sun Microsystems - Beijing China cca = RT2661_READ(sc, RT2661_STA_CSR1) & 0xffff;
192910115c80Sfei feng - Sun Microsystems - Beijing China
193010115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_rx_tune(): "
193110115c80Sfei feng - Sun Microsystems - Beijing China "RSSI=%ddBm false CCA=%d\n", dbm, cca);
193210115c80Sfei feng - Sun Microsystems - Beijing China
193310115c80Sfei feng - Sun Microsystems - Beijing China if (dbm < -74) {
193410115c80Sfei feng - Sun Microsystems - Beijing China /* very bad RSSI, tune using false CCA count */
193510115c80Sfei feng - Sun Microsystems - Beijing China bbp17 = sc->bbp17; /* current value */
193610115c80Sfei feng - Sun Microsystems - Beijing China
193710115c80Sfei feng - Sun Microsystems - Beijing China hi -= 2 * (-74 - dbm);
193810115c80Sfei feng - Sun Microsystems - Beijing China if (hi < lo)
193910115c80Sfei feng - Sun Microsystems - Beijing China hi = lo;
194010115c80Sfei feng - Sun Microsystems - Beijing China
194110115c80Sfei feng - Sun Microsystems - Beijing China if (bbp17 > hi)
194210115c80Sfei feng - Sun Microsystems - Beijing China bbp17 = (uint8_t)hi;
194310115c80Sfei feng - Sun Microsystems - Beijing China else if (cca > 512)
194410115c80Sfei feng - Sun Microsystems - Beijing China bbp17 = (uint8_t)min(bbp17 + 1, hi);
194510115c80Sfei feng - Sun Microsystems - Beijing China else if (cca < 100)
194610115c80Sfei feng - Sun Microsystems - Beijing China bbp17 = (uint8_t)max(bbp17 - 1, lo);
194710115c80Sfei feng - Sun Microsystems - Beijing China
194810115c80Sfei feng - Sun Microsystems - Beijing China } else if (dbm < -66) {
194910115c80Sfei feng - Sun Microsystems - Beijing China bbp17 = lo + 0x08;
195010115c80Sfei feng - Sun Microsystems - Beijing China } else if (dbm < -58) {
195110115c80Sfei feng - Sun Microsystems - Beijing China bbp17 = lo + 0x10;
195210115c80Sfei feng - Sun Microsystems - Beijing China } else if (dbm < -35) {
195310115c80Sfei feng - Sun Microsystems - Beijing China bbp17 = (uint8_t)hi;
195410115c80Sfei feng - Sun Microsystems - Beijing China } else { /* very good RSSI >= -35dBm */
195510115c80Sfei feng - Sun Microsystems - Beijing China bbp17 = 0x60; /* very low sensitivity */
195610115c80Sfei feng - Sun Microsystems - Beijing China }
195710115c80Sfei feng - Sun Microsystems - Beijing China
195810115c80Sfei feng - Sun Microsystems - Beijing China if (bbp17 != sc->bbp17) {
195910115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_tune(): "
196010115c80Sfei feng - Sun Microsystems - Beijing China "BBP17 %x->%x\n", sc->bbp17, bbp17);
196110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, 17, bbp17);
196210115c80Sfei feng - Sun Microsystems - Beijing China sc->bbp17 = bbp17;
196310115c80Sfei feng - Sun Microsystems - Beijing China }
196410115c80Sfei feng - Sun Microsystems - Beijing China }
196510115c80Sfei feng - Sun Microsystems - Beijing China
196610115c80Sfei feng - Sun Microsystems - Beijing China /*
196710115c80Sfei feng - Sun Microsystems - Beijing China * This function is called periodically (every 500ms) in RUN state to update
196810115c80Sfei feng - Sun Microsystems - Beijing China * various settings like rate control statistics or Rx sensitivity.
196910115c80Sfei feng - Sun Microsystems - Beijing China */
197010115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_updatestats(void * arg)197110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_updatestats(void *arg)
197210115c80Sfei feng - Sun Microsystems - Beijing China {
197310115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = arg;
197410115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
197510115c80Sfei feng - Sun Microsystems - Beijing China
197610115c80Sfei feng - Sun Microsystems - Beijing China if (ic->ic_opmode == IEEE80211_M_STA)
197710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_iter_func(sc, ic->ic_bss);
197810115c80Sfei feng - Sun Microsystems - Beijing China else
197910115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_iterate_nodes(&ic->ic_sta, rt2661_iter_func, arg);
198010115c80Sfei feng - Sun Microsystems - Beijing China
198110115c80Sfei feng - Sun Microsystems - Beijing China /* update rx sensitivity every 1 sec */
198210115c80Sfei feng - Sun Microsystems - Beijing China if (++sc->ncalls & 1)
198310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rx_tune(sc);
198410115c80Sfei feng - Sun Microsystems - Beijing China
198510115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_rssadapt_id = timeout(rt2661_updatestats, (void *)sc,
198610115c80Sfei feng - Sun Microsystems - Beijing China drv_usectohz(200 * 1000));
198710115c80Sfei feng - Sun Microsystems - Beijing China }
198810115c80Sfei feng - Sun Microsystems - Beijing China
198910115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_newstate(struct ieee80211com * ic,enum ieee80211_state nstate,int arg)199010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
199110115c80Sfei feng - Sun Microsystems - Beijing China {
199210115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)ic;
199310115c80Sfei feng - Sun Microsystems - Beijing China enum ieee80211_state ostate;
199410115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni;
199510115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
199610115c80Sfei feng - Sun Microsystems - Beijing China int err;
199710115c80Sfei feng - Sun Microsystems - Beijing China
199810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GLOCK(sc);
199910115c80Sfei feng - Sun Microsystems - Beijing China
200010115c80Sfei feng - Sun Microsystems - Beijing China ostate = ic->ic_state;
200110115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_ostate = ostate;
200210115c80Sfei feng - Sun Microsystems - Beijing China
200310115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt26661_newstate(): "
200410115c80Sfei feng - Sun Microsystems - Beijing China "%x -> %x\n", ostate, nstate);
200510115c80Sfei feng - Sun Microsystems - Beijing China
200610115c80Sfei feng - Sun Microsystems - Beijing China if (sc->sc_scan_id != 0) {
200710115c80Sfei feng - Sun Microsystems - Beijing China (void) untimeout(sc->sc_scan_id);
200810115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_scan_id = 0;
200910115c80Sfei feng - Sun Microsystems - Beijing China }
201010115c80Sfei feng - Sun Microsystems - Beijing China
201110115c80Sfei feng - Sun Microsystems - Beijing China if (sc->sc_rssadapt_id) {
201210115c80Sfei feng - Sun Microsystems - Beijing China (void) untimeout(sc->sc_rssadapt_id);
201310115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_rssadapt_id = 0;
201410115c80Sfei feng - Sun Microsystems - Beijing China }
201510115c80Sfei feng - Sun Microsystems - Beijing China
201610115c80Sfei feng - Sun Microsystems - Beijing China switch (nstate) {
201710115c80Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_INIT:
201810115c80Sfei feng - Sun Microsystems - Beijing China if (ostate == IEEE80211_S_RUN) {
201910115c80Sfei feng - Sun Microsystems - Beijing China /* abort TSF synchronization */
202010115c80Sfei feng - Sun Microsystems - Beijing China tmp = RT2661_READ(sc, RT2661_TXRX_CSR9);
202110115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TXRX_CSR9, tmp & ~0x00ffffff);
202210115c80Sfei feng - Sun Microsystems - Beijing China }
202310115c80Sfei feng - Sun Microsystems - Beijing China break;
202410115c80Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_SCAN:
202510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_chan(sc, ic->ic_curchan);
202610115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_scan_id = timeout(rt2661_next_scan, (void *)sc,
202710115c80Sfei feng - Sun Microsystems - Beijing China drv_usectohz(200000));
202810115c80Sfei feng - Sun Microsystems - Beijing China break;
202910115c80Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_AUTH:
203010115c80Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_ASSOC:
203110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_chan(sc, ic->ic_curchan);
203210115c80Sfei feng - Sun Microsystems - Beijing China break;
203310115c80Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_RUN:
203410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_chan(sc, ic->ic_curchan);
203510115c80Sfei feng - Sun Microsystems - Beijing China
203610115c80Sfei feng - Sun Microsystems - Beijing China ni = ic->ic_bss;
203710115c80Sfei feng - Sun Microsystems - Beijing China if (ic->ic_opmode != IEEE80211_M_MONITOR) {
203810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_slottime(sc);
203910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_enable_mrr(sc);
204010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_txpreamble(sc);
204110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_basicrates(sc);
204210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_bssid(sc, ni->in_bssid);
204310115c80Sfei feng - Sun Microsystems - Beijing China }
204410115c80Sfei feng - Sun Microsystems - Beijing China
204510115c80Sfei feng - Sun Microsystems - Beijing China if (ic->ic_opmode == IEEE80211_M_STA) {
204610115c80Sfei feng - Sun Microsystems - Beijing China /* fake a join to init the tx rate */
204710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_newassoc(ic, ni);
204810115c80Sfei feng - Sun Microsystems - Beijing China }
204910115c80Sfei feng - Sun Microsystems - Beijing China
205010115c80Sfei feng - Sun Microsystems - Beijing China if (ic->ic_opmode != IEEE80211_M_MONITOR) {
205110115c80Sfei feng - Sun Microsystems - Beijing China sc->ncalls = 0;
205210115c80Sfei feng - Sun Microsystems - Beijing China sc->avg_rssi = -95; /* reset EMA */
205310115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_rssadapt_id = timeout(rt2661_updatestats,
205410115c80Sfei feng - Sun Microsystems - Beijing China (void *)sc, drv_usectohz(200 * 1000));
205510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_enable_tsf_sync(sc);
205610115c80Sfei feng - Sun Microsystems - Beijing China }
205710115c80Sfei feng - Sun Microsystems - Beijing China break;
205810115c80Sfei feng - Sun Microsystems - Beijing China default:
205910115c80Sfei feng - Sun Microsystems - Beijing China break;
206010115c80Sfei feng - Sun Microsystems - Beijing China }
206110115c80Sfei feng - Sun Microsystems - Beijing China
206210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
206310115c80Sfei feng - Sun Microsystems - Beijing China
206410115c80Sfei feng - Sun Microsystems - Beijing China err = sc->sc_newstate(ic, nstate, arg);
206510115c80Sfei feng - Sun Microsystems - Beijing China return (err);
206610115c80Sfei feng - Sun Microsystems - Beijing China }
206710115c80Sfei feng - Sun Microsystems - Beijing China
206810115c80Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/
206910115c80Sfei feng - Sun Microsystems - Beijing China static struct ieee80211_node *
rt2661_node_alloc(ieee80211com_t * ic)207010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_node_alloc(ieee80211com_t *ic)
207110115c80Sfei feng - Sun Microsystems - Beijing China {
207210115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_node *rn;
207310115c80Sfei feng - Sun Microsystems - Beijing China
207410115c80Sfei feng - Sun Microsystems - Beijing China rn = kmem_zalloc(sizeof (struct rt2661_node), KM_SLEEP);
207510115c80Sfei feng - Sun Microsystems - Beijing China return ((rn != NULL) ? &rn->ni : NULL);
207610115c80Sfei feng - Sun Microsystems - Beijing China }
207710115c80Sfei feng - Sun Microsystems - Beijing China
207810115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_node_free(struct ieee80211_node * in)207910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_node_free(struct ieee80211_node *in)
208010115c80Sfei feng - Sun Microsystems - Beijing China {
208110115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = in->in_ic;
208210115c80Sfei feng - Sun Microsystems - Beijing China
208310115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_node_cleanup(in);
208410115c80Sfei feng - Sun Microsystems - Beijing China if (in->in_wpa_ie != NULL)
208510115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_free(in->in_wpa_ie);
208610115c80Sfei feng - Sun Microsystems - Beijing China kmem_free(in, sizeof (struct rt2661_node));
208710115c80Sfei feng - Sun Microsystems - Beijing China }
208810115c80Sfei feng - Sun Microsystems - Beijing China
208910115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_stop_locked(struct rt2661_softc * sc)209010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_stop_locked(struct rt2661_softc *sc)
209110115c80Sfei feng - Sun Microsystems - Beijing China {
209210115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
209310115c80Sfei feng - Sun Microsystems - Beijing China
209410115c80Sfei feng - Sun Microsystems - Beijing China if (RT2661_IS_RUNNING(sc)) {
209510115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_timer = 0;
209610115c80Sfei feng - Sun Microsystems - Beijing China
209710115c80Sfei feng - Sun Microsystems - Beijing China /* abort Tx (for all 5 Tx rings) */
209810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TX_CNTL_CSR, 0x1f << 16);
209910115c80Sfei feng - Sun Microsystems - Beijing China
210010115c80Sfei feng - Sun Microsystems - Beijing China /* disable Rx (value remains after reset!) */
210110115c80Sfei feng - Sun Microsystems - Beijing China tmp = RT2661_READ(sc, RT2661_TXRX_CSR0);
210210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX);
210310115c80Sfei feng - Sun Microsystems - Beijing China
210410115c80Sfei feng - Sun Microsystems - Beijing China /* reset ASIC */
210510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MAC_CSR1, 3);
210610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MAC_CSR1, 0);
210710115c80Sfei feng - Sun Microsystems - Beijing China
210810115c80Sfei feng - Sun Microsystems - Beijing China /* disable interrupts */
210910115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f);
211010115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff);
211110115c80Sfei feng - Sun Microsystems - Beijing China
211210115c80Sfei feng - Sun Microsystems - Beijing China /* clear any pending interrupt */
211310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff);
211410115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, 0xffffffff);
211510115c80Sfei feng - Sun Microsystems - Beijing China
211610115c80Sfei feng - Sun Microsystems - Beijing China /* reset Tx and Rx rings */
211710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_reset_tx_ring(sc, &sc->txq[0]);
211810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_reset_tx_ring(sc, &sc->txq[1]);
211910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_reset_tx_ring(sc, &sc->txq[2]);
212010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_reset_tx_ring(sc, &sc->txq[3]);
212110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_reset_tx_ring(sc, &sc->mgtq);
212210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_reset_rx_ring(sc, &sc->rxq);
212310115c80Sfei feng - Sun Microsystems - Beijing China }
212410115c80Sfei feng - Sun Microsystems - Beijing China }
212510115c80Sfei feng - Sun Microsystems - Beijing China
212610115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_set_macaddr(struct rt2661_softc * sc,const uint8_t * addr)212710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_macaddr(struct rt2661_softc *sc, const uint8_t *addr)
212810115c80Sfei feng - Sun Microsystems - Beijing China {
212910115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
213010115c80Sfei feng - Sun Microsystems - Beijing China
213110115c80Sfei feng - Sun Microsystems - Beijing China tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
213210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MAC_CSR2, tmp);
213310115c80Sfei feng - Sun Microsystems - Beijing China
213410115c80Sfei feng - Sun Microsystems - Beijing China tmp = addr[4] | addr[5] << 8 | 0xff << 16;
213510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MAC_CSR3, tmp);
213610115c80Sfei feng - Sun Microsystems - Beijing China }
213710115c80Sfei feng - Sun Microsystems - Beijing China
213810115c80Sfei feng - Sun Microsystems - Beijing China static uint8_t
rt2661_bbp_read(struct rt2661_softc * sc,uint8_t reg)213910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_read(struct rt2661_softc *sc, uint8_t reg)
214010115c80Sfei feng - Sun Microsystems - Beijing China {
214110115c80Sfei feng - Sun Microsystems - Beijing China uint32_t val;
214210115c80Sfei feng - Sun Microsystems - Beijing China int ntries;
214310115c80Sfei feng - Sun Microsystems - Beijing China
214410115c80Sfei feng - Sun Microsystems - Beijing China for (ntries = 0; ntries < 100; ntries++) {
214510115c80Sfei feng - Sun Microsystems - Beijing China if (!(RT2661_READ(sc, RT2661_PHY_CSR3) & RT2661_BBP_BUSY))
214610115c80Sfei feng - Sun Microsystems - Beijing China break;
214710115c80Sfei feng - Sun Microsystems - Beijing China DELAY(1);
214810115c80Sfei feng - Sun Microsystems - Beijing China }
214910115c80Sfei feng - Sun Microsystems - Beijing China if (ntries == 100) {
215010115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_read(): "
215110115c80Sfei feng - Sun Microsystems - Beijing China "could not read from BBP\n");
215210115c80Sfei feng - Sun Microsystems - Beijing China return (0);
215310115c80Sfei feng - Sun Microsystems - Beijing China }
215410115c80Sfei feng - Sun Microsystems - Beijing China
215510115c80Sfei feng - Sun Microsystems - Beijing China val = RT2661_BBP_BUSY | RT2661_BBP_READ | reg << 8;
215610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_PHY_CSR3, val);
215710115c80Sfei feng - Sun Microsystems - Beijing China
215810115c80Sfei feng - Sun Microsystems - Beijing China for (ntries = 0; ntries < 100; ntries++) {
215910115c80Sfei feng - Sun Microsystems - Beijing China val = RT2661_READ(sc, RT2661_PHY_CSR3);
216010115c80Sfei feng - Sun Microsystems - Beijing China if (!(val & RT2661_BBP_BUSY))
216110115c80Sfei feng - Sun Microsystems - Beijing China return (val & 0xff);
216210115c80Sfei feng - Sun Microsystems - Beijing China DELAY(1);
216310115c80Sfei feng - Sun Microsystems - Beijing China }
216410115c80Sfei feng - Sun Microsystems - Beijing China
216510115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_read(): "
216610115c80Sfei feng - Sun Microsystems - Beijing China "could not read from BBP\n");
216710115c80Sfei feng - Sun Microsystems - Beijing China return (0);
216810115c80Sfei feng - Sun Microsystems - Beijing China }
216910115c80Sfei feng - Sun Microsystems - Beijing China
217010115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_bbp_init(struct rt2661_softc * sc)217110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_init(struct rt2661_softc *sc)
217210115c80Sfei feng - Sun Microsystems - Beijing China {
217310115c80Sfei feng - Sun Microsystems - Beijing China #define N(a) (sizeof (a) / sizeof ((a)[0]))
217410115c80Sfei feng - Sun Microsystems - Beijing China
217510115c80Sfei feng - Sun Microsystems - Beijing China int i, ntries;
217610115c80Sfei feng - Sun Microsystems - Beijing China uint8_t val;
217710115c80Sfei feng - Sun Microsystems - Beijing China
217810115c80Sfei feng - Sun Microsystems - Beijing China /* wait for BBP to be ready */
217910115c80Sfei feng - Sun Microsystems - Beijing China for (ntries = 0; ntries < 100; ntries++) {
218010115c80Sfei feng - Sun Microsystems - Beijing China val = rt2661_bbp_read(sc, 0);
218110115c80Sfei feng - Sun Microsystems - Beijing China if (val != 0 && val != 0xff)
218210115c80Sfei feng - Sun Microsystems - Beijing China break;
218310115c80Sfei feng - Sun Microsystems - Beijing China DELAY(100);
218410115c80Sfei feng - Sun Microsystems - Beijing China }
218510115c80Sfei feng - Sun Microsystems - Beijing China if (ntries == 100) {
218610115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_init(): "
218710115c80Sfei feng - Sun Microsystems - Beijing China "timeout waiting for BBP\n");
218810115c80Sfei feng - Sun Microsystems - Beijing China return (RT2661_FAILURE);
218910115c80Sfei feng - Sun Microsystems - Beijing China }
219010115c80Sfei feng - Sun Microsystems - Beijing China
219110115c80Sfei feng - Sun Microsystems - Beijing China /* initialize BBP registers to default values */
219210115c80Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < N(rt2661_def_bbp); i++) {
219310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, rt2661_def_bbp[i].reg,
219410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_def_bbp[i].val);
219510115c80Sfei feng - Sun Microsystems - Beijing China }
219610115c80Sfei feng - Sun Microsystems - Beijing China
219710115c80Sfei feng - Sun Microsystems - Beijing China /* write vendor-specific BBP values (from EEPROM) */
219810115c80Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < 16; i++) {
219910115c80Sfei feng - Sun Microsystems - Beijing China if (sc->bbp_prom[i].reg == 0)
220010115c80Sfei feng - Sun Microsystems - Beijing China continue;
220110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
220210115c80Sfei feng - Sun Microsystems - Beijing China }
220310115c80Sfei feng - Sun Microsystems - Beijing China
220410115c80Sfei feng - Sun Microsystems - Beijing China return (RT2661_SUCCESS);
220510115c80Sfei feng - Sun Microsystems - Beijing China #undef N
220610115c80Sfei feng - Sun Microsystems - Beijing China }
220710115c80Sfei feng - Sun Microsystems - Beijing China
220810115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_bbp_write(struct rt2661_softc * sc,uint8_t reg,uint8_t val)220910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(struct rt2661_softc *sc, uint8_t reg, uint8_t val)
221010115c80Sfei feng - Sun Microsystems - Beijing China {
221110115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
221210115c80Sfei feng - Sun Microsystems - Beijing China int ntries;
221310115c80Sfei feng - Sun Microsystems - Beijing China
221410115c80Sfei feng - Sun Microsystems - Beijing China for (ntries = 0; ntries < 100; ntries++) {
221510115c80Sfei feng - Sun Microsystems - Beijing China if (!(RT2661_READ(sc, RT2661_PHY_CSR3) & RT2661_BBP_BUSY))
221610115c80Sfei feng - Sun Microsystems - Beijing China break;
221710115c80Sfei feng - Sun Microsystems - Beijing China DELAY(1);
221810115c80Sfei feng - Sun Microsystems - Beijing China }
221910115c80Sfei feng - Sun Microsystems - Beijing China if (ntries == 100) {
222010115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_write(): "
222110115c80Sfei feng - Sun Microsystems - Beijing China "could not write to BBP\n");
222210115c80Sfei feng - Sun Microsystems - Beijing China return;
222310115c80Sfei feng - Sun Microsystems - Beijing China }
222410115c80Sfei feng - Sun Microsystems - Beijing China
222510115c80Sfei feng - Sun Microsystems - Beijing China tmp = RT2661_BBP_BUSY | (reg & 0x7f) << 8 | val;
222610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_PHY_CSR3, tmp);
222710115c80Sfei feng - Sun Microsystems - Beijing China
222810115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_HW, "rwd: rt2661_bbp_write(): "
222910115c80Sfei feng - Sun Microsystems - Beijing China "BBP R%u <- 0x%02x\n", reg, val);
223010115c80Sfei feng - Sun Microsystems - Beijing China }
223110115c80Sfei feng - Sun Microsystems - Beijing China
223210115c80Sfei feng - Sun Microsystems - Beijing China /*
223310115c80Sfei feng - Sun Microsystems - Beijing China * Reprogram MAC/BBP to switch to a new band. Values taken from the reference
223410115c80Sfei feng - Sun Microsystems - Beijing China * driver.
223510115c80Sfei feng - Sun Microsystems - Beijing China */
223610115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_select_band(struct rt2661_softc * sc,struct ieee80211_channel * c)223710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_select_band(struct rt2661_softc *sc, struct ieee80211_channel *c)
223810115c80Sfei feng - Sun Microsystems - Beijing China {
223910115c80Sfei feng - Sun Microsystems - Beijing China uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
224010115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
224110115c80Sfei feng - Sun Microsystems - Beijing China
224210115c80Sfei feng - Sun Microsystems - Beijing China /* update all BBP registers that depend on the band */
224310115c80Sfei feng - Sun Microsystems - Beijing China bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c;
224410115c80Sfei feng - Sun Microsystems - Beijing China bbp35 = 0x50; bbp97 = 0x48; bbp98 = 0x48;
224510115c80Sfei feng - Sun Microsystems - Beijing China if (IEEE80211_IS_CHAN_5GHZ(c)) {
224610115c80Sfei feng - Sun Microsystems - Beijing China bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c;
224710115c80Sfei feng - Sun Microsystems - Beijing China bbp35 += 0x10; bbp97 += 0x10; bbp98 += 0x10;
224810115c80Sfei feng - Sun Microsystems - Beijing China }
224910115c80Sfei feng - Sun Microsystems - Beijing China if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
225010115c80Sfei feng - Sun Microsystems - Beijing China (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
225110115c80Sfei feng - Sun Microsystems - Beijing China bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
225210115c80Sfei feng - Sun Microsystems - Beijing China }
225310115c80Sfei feng - Sun Microsystems - Beijing China
225410115c80Sfei feng - Sun Microsystems - Beijing China sc->bbp17 = bbp17;
225510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, 17, bbp17);
225610115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, 96, bbp96);
225710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, 104, bbp104);
225810115c80Sfei feng - Sun Microsystems - Beijing China
225910115c80Sfei feng - Sun Microsystems - Beijing China if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
226010115c80Sfei feng - Sun Microsystems - Beijing China (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
226110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, 75, 0x80);
226210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, 86, 0x80);
226310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, 88, 0x80);
226410115c80Sfei feng - Sun Microsystems - Beijing China }
226510115c80Sfei feng - Sun Microsystems - Beijing China
226610115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, 35, bbp35);
226710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, 97, bbp97);
226810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, 98, bbp98);
226910115c80Sfei feng - Sun Microsystems - Beijing China
227010115c80Sfei feng - Sun Microsystems - Beijing China tmp = RT2661_READ(sc, RT2661_PHY_CSR0);
227110115c80Sfei feng - Sun Microsystems - Beijing China tmp &= ~(RT2661_PA_PE_2GHZ | RT2661_PA_PE_5GHZ);
227210115c80Sfei feng - Sun Microsystems - Beijing China if (IEEE80211_IS_CHAN_2GHZ(c))
227310115c80Sfei feng - Sun Microsystems - Beijing China tmp |= RT2661_PA_PE_2GHZ;
227410115c80Sfei feng - Sun Microsystems - Beijing China else
227510115c80Sfei feng - Sun Microsystems - Beijing China tmp |= RT2661_PA_PE_5GHZ;
227610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_PHY_CSR0, tmp);
227710115c80Sfei feng - Sun Microsystems - Beijing China
227810115c80Sfei feng - Sun Microsystems - Beijing China /* 802.11a uses a 16 microseconds short interframe space */
227910115c80Sfei feng - Sun Microsystems - Beijing China sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10;
228010115c80Sfei feng - Sun Microsystems - Beijing China }
228110115c80Sfei feng - Sun Microsystems - Beijing China
228210115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_select_antenna(struct rt2661_softc * sc)228310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_select_antenna(struct rt2661_softc *sc)
228410115c80Sfei feng - Sun Microsystems - Beijing China {
228510115c80Sfei feng - Sun Microsystems - Beijing China uint8_t bbp4, bbp77;
228610115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
228710115c80Sfei feng - Sun Microsystems - Beijing China
228810115c80Sfei feng - Sun Microsystems - Beijing China bbp4 = rt2661_bbp_read(sc, 4);
228910115c80Sfei feng - Sun Microsystems - Beijing China bbp77 = rt2661_bbp_read(sc, 77);
229010115c80Sfei feng - Sun Microsystems - Beijing China
229110115c80Sfei feng - Sun Microsystems - Beijing China /* TBD */
229210115c80Sfei feng - Sun Microsystems - Beijing China
229310115c80Sfei feng - Sun Microsystems - Beijing China /* make sure Rx is disabled before switching antenna */
229410115c80Sfei feng - Sun Microsystems - Beijing China tmp = RT2661_READ(sc, RT2661_TXRX_CSR0);
229510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX);
229610115c80Sfei feng - Sun Microsystems - Beijing China
229710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, 4, bbp4);
229810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, 77, bbp77);
229910115c80Sfei feng - Sun Microsystems - Beijing China
230010115c80Sfei feng - Sun Microsystems - Beijing China /* restore Rx filter */
230110115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp);
230210115c80Sfei feng - Sun Microsystems - Beijing China }
230310115c80Sfei feng - Sun Microsystems - Beijing China
230410115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_rf_write(struct rt2661_softc * sc,uint8_t reg,uint32_t val)230510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf_write(struct rt2661_softc *sc, uint8_t reg, uint32_t val)
230610115c80Sfei feng - Sun Microsystems - Beijing China {
230710115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp;
230810115c80Sfei feng - Sun Microsystems - Beijing China int ntries;
230910115c80Sfei feng - Sun Microsystems - Beijing China
231010115c80Sfei feng - Sun Microsystems - Beijing China for (ntries = 0; ntries < 100; ntries++) {
231110115c80Sfei feng - Sun Microsystems - Beijing China if (!(RT2661_READ(sc, RT2661_PHY_CSR4) & RT2661_RF_BUSY))
231210115c80Sfei feng - Sun Microsystems - Beijing China break;
231310115c80Sfei feng - Sun Microsystems - Beijing China DELAY(1);
231410115c80Sfei feng - Sun Microsystems - Beijing China }
231510115c80Sfei feng - Sun Microsystems - Beijing China if (ntries == 100) {
231610115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rf_write(): "
231710115c80Sfei feng - Sun Microsystems - Beijing China "could not write to RF\n");
231810115c80Sfei feng - Sun Microsystems - Beijing China return;
231910115c80Sfei feng - Sun Microsystems - Beijing China }
232010115c80Sfei feng - Sun Microsystems - Beijing China
232110115c80Sfei feng - Sun Microsystems - Beijing China tmp = RT2661_RF_BUSY | RT2661_RF_21BIT | (val & 0x1fffff) << 2 |
232210115c80Sfei feng - Sun Microsystems - Beijing China (reg & 3);
232310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_PHY_CSR4, tmp);
232410115c80Sfei feng - Sun Microsystems - Beijing China
232510115c80Sfei feng - Sun Microsystems - Beijing China /* remember last written value in sc */
232610115c80Sfei feng - Sun Microsystems - Beijing China sc->rf_regs[reg] = val;
232710115c80Sfei feng - Sun Microsystems - Beijing China
232810115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_FW, "rwd: rt2661_rf_write(): "
232910115c80Sfei feng - Sun Microsystems - Beijing China "RF R[%u] <- 0x%05x\n", reg & 3, val & 0x1fffff);
233010115c80Sfei feng - Sun Microsystems - Beijing China }
233110115c80Sfei feng - Sun Microsystems - Beijing China
233210115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_set_chan(struct rt2661_softc * sc,struct ieee80211_channel * c)233310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_chan(struct rt2661_softc *sc, struct ieee80211_channel *c)
233410115c80Sfei feng - Sun Microsystems - Beijing China {
233510115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
233610115c80Sfei feng - Sun Microsystems - Beijing China const struct rfprog *rfprog;
233710115c80Sfei feng - Sun Microsystems - Beijing China uint8_t bbp3, bbp94 = RT2661_BBPR94_DEFAULT;
233810115c80Sfei feng - Sun Microsystems - Beijing China int8_t power;
233910115c80Sfei feng - Sun Microsystems - Beijing China uint_t i, chan;
234010115c80Sfei feng - Sun Microsystems - Beijing China
234110115c80Sfei feng - Sun Microsystems - Beijing China chan = ieee80211_chan2ieee(ic, c);
234210115c80Sfei feng - Sun Microsystems - Beijing China if (chan == 0 || chan == IEEE80211_CHAN_ANY)
234310115c80Sfei feng - Sun Microsystems - Beijing China return;
234410115c80Sfei feng - Sun Microsystems - Beijing China
234510115c80Sfei feng - Sun Microsystems - Beijing China /* select the appropriate RF settings based on what EEPROM says */
234610115c80Sfei feng - Sun Microsystems - Beijing China rfprog = (sc->rfprog == 0) ? rt2661_rf5225_1 : rt2661_rf5225_2;
234710115c80Sfei feng - Sun Microsystems - Beijing China
234810115c80Sfei feng - Sun Microsystems - Beijing China /* find the settings for this channel (we know it exists) */
234910115c80Sfei feng - Sun Microsystems - Beijing China i = 0;
235010115c80Sfei feng - Sun Microsystems - Beijing China while (rfprog[i].chan != chan)
235110115c80Sfei feng - Sun Microsystems - Beijing China i++;
235210115c80Sfei feng - Sun Microsystems - Beijing China
235310115c80Sfei feng - Sun Microsystems - Beijing China power = sc->txpow[i];
235410115c80Sfei feng - Sun Microsystems - Beijing China if (power < 0) {
235510115c80Sfei feng - Sun Microsystems - Beijing China bbp94 += power;
235610115c80Sfei feng - Sun Microsystems - Beijing China power = 0;
235710115c80Sfei feng - Sun Microsystems - Beijing China } else if (power > 31) {
235810115c80Sfei feng - Sun Microsystems - Beijing China bbp94 += power - 31;
235910115c80Sfei feng - Sun Microsystems - Beijing China power = 31;
236010115c80Sfei feng - Sun Microsystems - Beijing China }
236110115c80Sfei feng - Sun Microsystems - Beijing China
236210115c80Sfei feng - Sun Microsystems - Beijing China /*
236310115c80Sfei feng - Sun Microsystems - Beijing China * If we are switching from the 2GHz band to the 5GHz band or
236410115c80Sfei feng - Sun Microsystems - Beijing China * vice-versa, BBP registers need to be reprogrammed.
236510115c80Sfei feng - Sun Microsystems - Beijing China */
236610115c80Sfei feng - Sun Microsystems - Beijing China if (ic->ic_flags != sc->sc_curchan->ich_flags) {
236710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_select_band(sc, c);
236810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_select_antenna(sc);
236910115c80Sfei feng - Sun Microsystems - Beijing China }
237010115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_curchan = c;
237110115c80Sfei feng - Sun Microsystems - Beijing China
237210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf_write(sc, RT2661_RF1, rfprog[i].r1);
237310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf_write(sc, RT2661_RF2, rfprog[i].r2);
237410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf_write(sc, RT2661_RF3, rfprog[i].r3 | power << 7);
237510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf_write(sc, RT2661_RF4, rfprog[i].r4 | sc->rffreq << 10);
237610115c80Sfei feng - Sun Microsystems - Beijing China
237710115c80Sfei feng - Sun Microsystems - Beijing China DELAY(200);
237810115c80Sfei feng - Sun Microsystems - Beijing China
237910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf_write(sc, RT2661_RF1, rfprog[i].r1);
238010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf_write(sc, RT2661_RF2, rfprog[i].r2);
238110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf_write(sc, RT2661_RF3, rfprog[i].r3 | power << 7 | 1);
238210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf_write(sc, RT2661_RF4, rfprog[i].r4 | sc->rffreq << 10);
238310115c80Sfei feng - Sun Microsystems - Beijing China
238410115c80Sfei feng - Sun Microsystems - Beijing China DELAY(200);
238510115c80Sfei feng - Sun Microsystems - Beijing China
238610115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf_write(sc, RT2661_RF1, rfprog[i].r1);
238710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf_write(sc, RT2661_RF2, rfprog[i].r2);
238810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf_write(sc, RT2661_RF3, rfprog[i].r3 | power << 7);
238910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_rf_write(sc, RT2661_RF4, rfprog[i].r4 | sc->rffreq << 10);
239010115c80Sfei feng - Sun Microsystems - Beijing China
239110115c80Sfei feng - Sun Microsystems - Beijing China /* enable smart mode for MIMO-capable RFs */
239210115c80Sfei feng - Sun Microsystems - Beijing China bbp3 = rt2661_bbp_read(sc, 3);
239310115c80Sfei feng - Sun Microsystems - Beijing China
239410115c80Sfei feng - Sun Microsystems - Beijing China bbp3 &= ~RT2661_SMART_MODE;
239510115c80Sfei feng - Sun Microsystems - Beijing China if (sc->rf_rev == RT2661_RF_5325 || sc->rf_rev == RT2661_RF_2529)
239610115c80Sfei feng - Sun Microsystems - Beijing China bbp3 |= RT2661_SMART_MODE;
239710115c80Sfei feng - Sun Microsystems - Beijing China
239810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, 3, bbp3);
239910115c80Sfei feng - Sun Microsystems - Beijing China
240010115c80Sfei feng - Sun Microsystems - Beijing China if (bbp94 != RT2661_BBPR94_DEFAULT)
240110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_bbp_write(sc, 94, bbp94);
240210115c80Sfei feng - Sun Microsystems - Beijing China
240310115c80Sfei feng - Sun Microsystems - Beijing China /* 5GHz radio needs a 1ms delay here */
240410115c80Sfei feng - Sun Microsystems - Beijing China if (IEEE80211_IS_CHAN_5GHZ(c))
240510115c80Sfei feng - Sun Microsystems - Beijing China DELAY(1000);
240610115c80Sfei feng - Sun Microsystems - Beijing China }
240710115c80Sfei feng - Sun Microsystems - Beijing China
240810115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_init(struct rt2661_softc * sc)240910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_init(struct rt2661_softc *sc)
241010115c80Sfei feng - Sun Microsystems - Beijing China {
241110115c80Sfei feng - Sun Microsystems - Beijing China #define N(a) (sizeof (a) / sizeof ((a)[0]))
241210115c80Sfei feng - Sun Microsystems - Beijing China
241310115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
241410115c80Sfei feng - Sun Microsystems - Beijing China uint32_t tmp, sta[3], *fptr;
241510115c80Sfei feng - Sun Microsystems - Beijing China int i, err, off, ntries;
241610115c80Sfei feng - Sun Microsystems - Beijing China
241710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GLOCK(sc);
241810115c80Sfei feng - Sun Microsystems - Beijing China
241910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_stop_locked(sc);
242010115c80Sfei feng - Sun Microsystems - Beijing China
242110115c80Sfei feng - Sun Microsystems - Beijing China if (!RT2661_IS_FWLOADED(sc)) {
242210115c80Sfei feng - Sun Microsystems - Beijing China err = rt2661_load_microcode(sc, ucode, usize);
242310115c80Sfei feng - Sun Microsystems - Beijing China if (err != RT2661_SUCCESS) {
242410115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
242510115c80Sfei feng - Sun Microsystems - Beijing China "could not load 8051 microcode\n");
242610115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
242710115c80Sfei feng - Sun Microsystems - Beijing China }
242810115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_flags |= RT2661_F_FWLOADED;
242910115c80Sfei feng - Sun Microsystems - Beijing China }
243010115c80Sfei feng - Sun Microsystems - Beijing China
243110115c80Sfei feng - Sun Microsystems - Beijing China /* initialize Tx rings */
243210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_AC1_BASE_CSR, sc->txq[1].paddr);
243310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_AC0_BASE_CSR, sc->txq[0].paddr);
243410115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_AC2_BASE_CSR, sc->txq[2].paddr);
243510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_AC3_BASE_CSR, sc->txq[3].paddr);
243610115c80Sfei feng - Sun Microsystems - Beijing China
243710115c80Sfei feng - Sun Microsystems - Beijing China /* initialize Mgt ring */
243810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MGT_BASE_CSR, sc->mgtq.paddr);
243910115c80Sfei feng - Sun Microsystems - Beijing China
244010115c80Sfei feng - Sun Microsystems - Beijing China /* initialize Rx ring */
244110115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_RX_BASE_CSR, sc->rxq.paddr);
244210115c80Sfei feng - Sun Microsystems - Beijing China
244310115c80Sfei feng - Sun Microsystems - Beijing China /* initialize Tx rings sizes */
244410115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TX_RING_CSR0,
244510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_TX_RING_COUNT << 24 |
244610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_TX_RING_COUNT << 16 |
244710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_TX_RING_COUNT << 8 |
244810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_TX_RING_COUNT);
244910115c80Sfei feng - Sun Microsystems - Beijing China
245010115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TX_RING_CSR1,
245110115c80Sfei feng - Sun Microsystems - Beijing China RT2661_TX_DESC_WSIZE << 16 |
245210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_TX_RING_COUNT << 8 |
245310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_MGT_RING_COUNT);
245410115c80Sfei feng - Sun Microsystems - Beijing China
245510115c80Sfei feng - Sun Microsystems - Beijing China /* initialize Rx rings */
245610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_RX_RING_CSR,
245710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_RX_DESC_BACK << 16 |
245810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_RX_DESC_WSIZE << 8 |
245910115c80Sfei feng - Sun Microsystems - Beijing China RT2661_RX_RING_COUNT);
246010115c80Sfei feng - Sun Microsystems - Beijing China
246110115c80Sfei feng - Sun Microsystems - Beijing China /* XXX: some magic here */
246210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TX_DMA_DST_CSR, 0xaa);
246310115c80Sfei feng - Sun Microsystems - Beijing China
246410115c80Sfei feng - Sun Microsystems - Beijing China /* load base addresses of all 5 Tx rings (4 data + 1 mgt) */
246510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_LOAD_TX_RING_CSR, 0x1f);
246610115c80Sfei feng - Sun Microsystems - Beijing China
246710115c80Sfei feng - Sun Microsystems - Beijing China /* load base address of Rx ring */
246810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_RX_CNTL_CSR, 2);
246910115c80Sfei feng - Sun Microsystems - Beijing China
247010115c80Sfei feng - Sun Microsystems - Beijing China /* initialize MAC registers to default values */
247110115c80Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < N(rt2661_def_mac); i++)
247210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, rt2661_def_mac[i].reg, rt2661_def_mac[i].val);
247310115c80Sfei feng - Sun Microsystems - Beijing China
247410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_macaddr(sc, ic->ic_macaddr);
247510115c80Sfei feng - Sun Microsystems - Beijing China
247610115c80Sfei feng - Sun Microsystems - Beijing China /* set host ready */
247710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MAC_CSR1, 3);
247810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MAC_CSR1, 0);
247910115c80Sfei feng - Sun Microsystems - Beijing China
248010115c80Sfei feng - Sun Microsystems - Beijing China /* wait for BBP/RF to wakeup */
248110115c80Sfei feng - Sun Microsystems - Beijing China for (ntries = 0; ntries < 1000; ntries++) {
248210115c80Sfei feng - Sun Microsystems - Beijing China if (RT2661_READ(sc, RT2661_MAC_CSR12) & 8)
248310115c80Sfei feng - Sun Microsystems - Beijing China break;
248410115c80Sfei feng - Sun Microsystems - Beijing China DELAY(1000);
248510115c80Sfei feng - Sun Microsystems - Beijing China }
248610115c80Sfei feng - Sun Microsystems - Beijing China if (ntries == 1000) {
248710115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
248810115c80Sfei feng - Sun Microsystems - Beijing China "timeout waiting for BBP/RF to wakeup\n");
248910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_stop_locked(sc);
249010115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
249110115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
249210115c80Sfei feng - Sun Microsystems - Beijing China }
249310115c80Sfei feng - Sun Microsystems - Beijing China
249410115c80Sfei feng - Sun Microsystems - Beijing China if (rt2661_bbp_init(sc) != RT2661_SUCCESS) {
249510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_stop_locked(sc);
249610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
249710115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
249810115c80Sfei feng - Sun Microsystems - Beijing China }
249910115c80Sfei feng - Sun Microsystems - Beijing China
250010115c80Sfei feng - Sun Microsystems - Beijing China /* select default channel */
250110115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_curchan = ic->ic_bss->in_chan = ic->ic_curchan;
250210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_select_band(sc, sc->sc_curchan);
250310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_select_antenna(sc);
250410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_set_chan(sc, sc->sc_curchan);
250510115c80Sfei feng - Sun Microsystems - Beijing China
250610115c80Sfei feng - Sun Microsystems - Beijing China /* update Rx filter */
250710115c80Sfei feng - Sun Microsystems - Beijing China tmp = RT2661_READ(sc, RT2661_TXRX_CSR0) & 0xffff;
250810115c80Sfei feng - Sun Microsystems - Beijing China
250910115c80Sfei feng - Sun Microsystems - Beijing China tmp |= RT2661_DROP_PHY_ERROR | RT2661_DROP_CRC_ERROR;
251010115c80Sfei feng - Sun Microsystems - Beijing China if (ic->ic_opmode != IEEE80211_M_MONITOR) {
251110115c80Sfei feng - Sun Microsystems - Beijing China tmp |= RT2661_DROP_CTL | RT2661_DROP_VER_ERROR |
251210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_DROP_ACKCTS;
251310115c80Sfei feng - Sun Microsystems - Beijing China if (ic->ic_opmode != IEEE80211_M_HOSTAP)
251410115c80Sfei feng - Sun Microsystems - Beijing China tmp |= RT2661_DROP_TODS;
251510115c80Sfei feng - Sun Microsystems - Beijing China if (!(sc->sc_rcr & RT2661_RCR_PROMISC))
251610115c80Sfei feng - Sun Microsystems - Beijing China tmp |= RT2661_DROP_NOT_TO_ME;
251710115c80Sfei feng - Sun Microsystems - Beijing China }
251810115c80Sfei feng - Sun Microsystems - Beijing China
251910115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp);
252010115c80Sfei feng - Sun Microsystems - Beijing China
252110115c80Sfei feng - Sun Microsystems - Beijing China /* clear STA registers */
252210115c80Sfei feng - Sun Microsystems - Beijing China off = RT2661_STA_CSR0;
252310115c80Sfei feng - Sun Microsystems - Beijing China fptr = sta;
252410115c80Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < N(sta); i++) {
252510115c80Sfei feng - Sun Microsystems - Beijing China *fptr = RT2661_MEM_READ1(sc, off++);
252610115c80Sfei feng - Sun Microsystems - Beijing China }
252710115c80Sfei feng - Sun Microsystems - Beijing China
252810115c80Sfei feng - Sun Microsystems - Beijing China /* initialize ASIC */
252910115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MAC_CSR1, 4);
253010115c80Sfei feng - Sun Microsystems - Beijing China
253110115c80Sfei feng - Sun Microsystems - Beijing China /* clear any pending interrupt */
253210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff);
253310115c80Sfei feng - Sun Microsystems - Beijing China
253410115c80Sfei feng - Sun Microsystems - Beijing China /* enable interrupts */
253510115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0x0000ff10);
253610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0);
253710115c80Sfei feng - Sun Microsystems - Beijing China
253810115c80Sfei feng - Sun Microsystems - Beijing China /* kick Rx */
253910115c80Sfei feng - Sun Microsystems - Beijing China RT2661_WRITE(sc, RT2661_RX_CNTL_CSR, 1);
254010115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
254110115c80Sfei feng - Sun Microsystems - Beijing China
254210115c80Sfei feng - Sun Microsystems - Beijing China #undef N
254310115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
254410115c80Sfei feng - Sun Microsystems - Beijing China }
254510115c80Sfei feng - Sun Microsystems - Beijing China
254610115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_stop(struct rt2661_softc * sc)254710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_stop(struct rt2661_softc *sc)
254810115c80Sfei feng - Sun Microsystems - Beijing China {
254910115c80Sfei feng - Sun Microsystems - Beijing China if (!RT2661_IS_FASTREBOOT(sc))
255010115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GLOCK(sc);
255110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_stop_locked(sc);
255210115c80Sfei feng - Sun Microsystems - Beijing China if (!RT2661_IS_FASTREBOOT(sc))
255310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
255410115c80Sfei feng - Sun Microsystems - Beijing China }
255510115c80Sfei feng - Sun Microsystems - Beijing China
255610115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_m_start(void * arg)255710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_start(void *arg)
255810115c80Sfei feng - Sun Microsystems - Beijing China {
255910115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)arg;
256010115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
256110115c80Sfei feng - Sun Microsystems - Beijing China int err;
256210115c80Sfei feng - Sun Microsystems - Beijing China
256310115c80Sfei feng - Sun Microsystems - Beijing China err = rt2661_init(sc);
256410115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
256510115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_m_start():"
256610115c80Sfei feng - Sun Microsystems - Beijing China "Hardware initialization failed\n");
256710115c80Sfei feng - Sun Microsystems - Beijing China goto fail1;
256810115c80Sfei feng - Sun Microsystems - Beijing China }
256910115c80Sfei feng - Sun Microsystems - Beijing China
257010115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
257110115c80Sfei feng - Sun Microsystems - Beijing China
257210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GLOCK(sc);
257310115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_flags |= RT2661_F_RUNNING;
257410115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
257510115c80Sfei feng - Sun Microsystems - Beijing China
257610115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
257710115c80Sfei feng - Sun Microsystems - Beijing China fail1:
257810115c80Sfei feng - Sun Microsystems - Beijing China rt2661_stop(sc);
257910115c80Sfei feng - Sun Microsystems - Beijing China return (err);
258010115c80Sfei feng - Sun Microsystems - Beijing China }
258110115c80Sfei feng - Sun Microsystems - Beijing China
258210115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_m_stop(void * arg)258310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_stop(void *arg)
258410115c80Sfei feng - Sun Microsystems - Beijing China {
258510115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)arg;
258610115c80Sfei feng - Sun Microsystems - Beijing China
258710115c80Sfei feng - Sun Microsystems - Beijing China (void) rt2661_stop(sc);
258810115c80Sfei feng - Sun Microsystems - Beijing China
258910115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
259010115c80Sfei feng - Sun Microsystems - Beijing China
259110115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GLOCK(sc);
259210115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_flags &= ~RT2661_F_RUNNING;
259310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
259410115c80Sfei feng - Sun Microsystems - Beijing China }
259510115c80Sfei feng - Sun Microsystems - Beijing China
259610115c80Sfei feng - Sun Microsystems - Beijing China static void
rt2661_m_ioctl(void * arg,queue_t * wq,mblk_t * mp)259710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_ioctl(void* arg, queue_t *wq, mblk_t *mp)
259810115c80Sfei feng - Sun Microsystems - Beijing China {
259910115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)arg;
260010115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
260110115c80Sfei feng - Sun Microsystems - Beijing China int err;
260210115c80Sfei feng - Sun Microsystems - Beijing China
260310115c80Sfei feng - Sun Microsystems - Beijing China err = ieee80211_ioctl(ic, wq, mp);
260410115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GLOCK(sc);
260510115c80Sfei feng - Sun Microsystems - Beijing China if (err == ENETRESET) {
260610115c80Sfei feng - Sun Microsystems - Beijing China if (ic->ic_des_esslen) {
260710115c80Sfei feng - Sun Microsystems - Beijing China if (RT2661_IS_RUNNING(sc)) {
260810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
260910115c80Sfei feng - Sun Microsystems - Beijing China (void) rt2661_init(sc);
261010115c80Sfei feng - Sun Microsystems - Beijing China (void) ieee80211_new_state(ic,
261110115c80Sfei feng - Sun Microsystems - Beijing China IEEE80211_S_SCAN, -1);
261210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GLOCK(sc);
261310115c80Sfei feng - Sun Microsystems - Beijing China }
261410115c80Sfei feng - Sun Microsystems - Beijing China }
261510115c80Sfei feng - Sun Microsystems - Beijing China }
261610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
261710115c80Sfei feng - Sun Microsystems - Beijing China }
261810115c80Sfei feng - Sun Microsystems - Beijing China
261910115c80Sfei feng - Sun Microsystems - Beijing China /*
262010115c80Sfei feng - Sun Microsystems - Beijing China * Call back function for get/set proporty
262110115c80Sfei feng - Sun Microsystems - Beijing China */
262210115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_m_getprop(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,uint_t wldp_length,void * wldp_buf)262310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2624*0dc2366fSVenugopal Iyer uint_t wldp_length, void *wldp_buf)
262510115c80Sfei feng - Sun Microsystems - Beijing China {
262610115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)arg;
262710115c80Sfei feng - Sun Microsystems - Beijing China int err = 0;
262810115c80Sfei feng - Sun Microsystems - Beijing China
262910115c80Sfei feng - Sun Microsystems - Beijing China err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num,
2630*0dc2366fSVenugopal Iyer wldp_length, wldp_buf);
263110115c80Sfei feng - Sun Microsystems - Beijing China
263210115c80Sfei feng - Sun Microsystems - Beijing China return (err);
263310115c80Sfei feng - Sun Microsystems - Beijing China }
263410115c80Sfei feng - Sun Microsystems - Beijing China
2635*0dc2366fSVenugopal Iyer static void
rt2661_m_propinfo(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,mac_prop_info_handle_t mph)2636*0dc2366fSVenugopal Iyer rt2661_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2637*0dc2366fSVenugopal Iyer mac_prop_info_handle_t mph)
2638*0dc2366fSVenugopal Iyer {
2639*0dc2366fSVenugopal Iyer struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2640*0dc2366fSVenugopal Iyer
2641*0dc2366fSVenugopal Iyer ieee80211_propinfo(&sc->sc_ic, pr_name, wldp_pr_num, mph);
2642*0dc2366fSVenugopal Iyer }
2643*0dc2366fSVenugopal Iyer
264410115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_m_setprop(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,uint_t wldp_length,const void * wldp_buf)264510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
264610115c80Sfei feng - Sun Microsystems - Beijing China uint_t wldp_length, const void *wldp_buf)
264710115c80Sfei feng - Sun Microsystems - Beijing China {
264810115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)arg;
264910115c80Sfei feng - Sun Microsystems - Beijing China ieee80211com_t *ic = &sc->sc_ic;
265010115c80Sfei feng - Sun Microsystems - Beijing China int err;
265110115c80Sfei feng - Sun Microsystems - Beijing China
265210115c80Sfei feng - Sun Microsystems - Beijing China err = ieee80211_setprop(ic, pr_name, wldp_pr_num, wldp_length,
265310115c80Sfei feng - Sun Microsystems - Beijing China wldp_buf);
265410115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GLOCK(sc);
265510115c80Sfei feng - Sun Microsystems - Beijing China if (err == ENETRESET) {
265610115c80Sfei feng - Sun Microsystems - Beijing China if (ic->ic_des_esslen) {
265710115c80Sfei feng - Sun Microsystems - Beijing China if (RT2661_IS_RUNNING(sc)) {
265810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
265910115c80Sfei feng - Sun Microsystems - Beijing China (void) rt2661_init(sc);
266010115c80Sfei feng - Sun Microsystems - Beijing China (void) ieee80211_new_state(ic,
266110115c80Sfei feng - Sun Microsystems - Beijing China IEEE80211_S_SCAN, -1);
266210115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GLOCK(sc);
266310115c80Sfei feng - Sun Microsystems - Beijing China }
266410115c80Sfei feng - Sun Microsystems - Beijing China }
266510115c80Sfei feng - Sun Microsystems - Beijing China err = 0;
266610115c80Sfei feng - Sun Microsystems - Beijing China }
266710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
266810115c80Sfei feng - Sun Microsystems - Beijing China return (err);
266910115c80Sfei feng - Sun Microsystems - Beijing China }
267010115c80Sfei feng - Sun Microsystems - Beijing China
267110115c80Sfei feng - Sun Microsystems - Beijing China static mblk_t *
rt2661_m_tx(void * arg,mblk_t * mp)267210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_tx(void *arg, mblk_t *mp)
267310115c80Sfei feng - Sun Microsystems - Beijing China {
267410115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)arg;
267510115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
267610115c80Sfei feng - Sun Microsystems - Beijing China mblk_t *next;
267710115c80Sfei feng - Sun Microsystems - Beijing China
267810115c80Sfei feng - Sun Microsystems - Beijing China if (RT2661_IS_SUSPEND(sc)) {
267910115c80Sfei feng - Sun Microsystems - Beijing China freemsgchain(mp);
268010115c80Sfei feng - Sun Microsystems - Beijing China return (NULL);
268110115c80Sfei feng - Sun Microsystems - Beijing China }
268210115c80Sfei feng - Sun Microsystems - Beijing China
268310115c80Sfei feng - Sun Microsystems - Beijing China /*
268410115c80Sfei feng - Sun Microsystems - Beijing China * No data frames go out unless we're associated; this
268510115c80Sfei feng - Sun Microsystems - Beijing China * should not happen as the 802.11 layer does not enable
268610115c80Sfei feng - Sun Microsystems - Beijing China * the xmit queue until we enter the RUN state.
268710115c80Sfei feng - Sun Microsystems - Beijing China */
268810115c80Sfei feng - Sun Microsystems - Beijing China if (ic->ic_state != IEEE80211_S_RUN) {
268910115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_data(): "
269010115c80Sfei feng - Sun Microsystems - Beijing China "discard, state %u\n", ic->ic_state);
269110115c80Sfei feng - Sun Microsystems - Beijing China freemsgchain(mp);
269210115c80Sfei feng - Sun Microsystems - Beijing China return (NULL);
269310115c80Sfei feng - Sun Microsystems - Beijing China }
269410115c80Sfei feng - Sun Microsystems - Beijing China
269510115c80Sfei feng - Sun Microsystems - Beijing China while (mp != NULL) {
269610115c80Sfei feng - Sun Microsystems - Beijing China next = mp->b_next;
269710115c80Sfei feng - Sun Microsystems - Beijing China mp->b_next = NULL;
269810115c80Sfei feng - Sun Microsystems - Beijing China if (rt2661_send(ic, mp) !=
269910115c80Sfei feng - Sun Microsystems - Beijing China DDI_SUCCESS) {
270010115c80Sfei feng - Sun Microsystems - Beijing China mp->b_next = next;
270110115c80Sfei feng - Sun Microsystems - Beijing China break;
270210115c80Sfei feng - Sun Microsystems - Beijing China }
270310115c80Sfei feng - Sun Microsystems - Beijing China mp = next;
270410115c80Sfei feng - Sun Microsystems - Beijing China }
270510115c80Sfei feng - Sun Microsystems - Beijing China return (mp);
270610115c80Sfei feng - Sun Microsystems - Beijing China }
270710115c80Sfei feng - Sun Microsystems - Beijing China
270810115c80Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/
270910115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_m_unicst(void * arg,const uint8_t * macaddr)271010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_unicst(void *arg, const uint8_t *macaddr)
271110115c80Sfei feng - Sun Microsystems - Beijing China {
271210115c80Sfei feng - Sun Microsystems - Beijing China return (ENOTSUP);
271310115c80Sfei feng - Sun Microsystems - Beijing China }
271410115c80Sfei feng - Sun Microsystems - Beijing China
271510115c80Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/
271610115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_m_multicst(void * arg,boolean_t add,const uint8_t * mca)271710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
271810115c80Sfei feng - Sun Microsystems - Beijing China {
271910115c80Sfei feng - Sun Microsystems - Beijing China return (ENOTSUP);
272010115c80Sfei feng - Sun Microsystems - Beijing China }
272110115c80Sfei feng - Sun Microsystems - Beijing China
272210115c80Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/
272310115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_m_promisc(void * arg,boolean_t on)272410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_promisc(void *arg, boolean_t on)
272510115c80Sfei feng - Sun Microsystems - Beijing China {
272610115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)arg;
272710115c80Sfei feng - Sun Microsystems - Beijing China
272810115c80Sfei feng - Sun Microsystems - Beijing China if (on) {
272910115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_rcr |= RT2661_RCR_PROMISC;
273010115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_rcr |= RT2661_RCR_MULTI;
273110115c80Sfei feng - Sun Microsystems - Beijing China } else {
273210115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_rcr &= ~RT2661_RCR_PROMISC;
273310115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_rcr &= ~RT2661_RCR_MULTI;
273410115c80Sfei feng - Sun Microsystems - Beijing China }
273510115c80Sfei feng - Sun Microsystems - Beijing China
273610115c80Sfei feng - Sun Microsystems - Beijing China rt2661_update_promisc(sc);
273710115c80Sfei feng - Sun Microsystems - Beijing China return (0);
273810115c80Sfei feng - Sun Microsystems - Beijing China }
273910115c80Sfei feng - Sun Microsystems - Beijing China
274010115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_m_stat(void * arg,uint_t stat,uint64_t * val)274110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_m_stat(void *arg, uint_t stat, uint64_t *val)
274210115c80Sfei feng - Sun Microsystems - Beijing China {
274310115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc = (struct rt2661_softc *)arg;
274410115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
274510115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni = ic->ic_bss;
274610115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211_rateset *rs = &ni->in_rates;
274710115c80Sfei feng - Sun Microsystems - Beijing China
274810115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GLOCK(sc);
274910115c80Sfei feng - Sun Microsystems - Beijing China switch (stat) {
275010115c80Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_IFSPEED:
275110115c80Sfei feng - Sun Microsystems - Beijing China *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
275210115c80Sfei feng - Sun Microsystems - Beijing China (rs->ir_rates[ni->in_txrate] & IEEE80211_RATE_VAL)
275310115c80Sfei feng - Sun Microsystems - Beijing China : ic->ic_fixed_rate) / 2 * 1000000;
275410115c80Sfei feng - Sun Microsystems - Beijing China break;
275510115c80Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_NOXMTBUF:
275610115c80Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_tx_nobuf;
275710115c80Sfei feng - Sun Microsystems - Beijing China break;
275810115c80Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_NORCVBUF:
275910115c80Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_rx_nobuf;
276010115c80Sfei feng - Sun Microsystems - Beijing China break;
276110115c80Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_IERRORS:
276210115c80Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_rx_err;
276310115c80Sfei feng - Sun Microsystems - Beijing China break;
276410115c80Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_RBYTES:
276510115c80Sfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_rx_bytes;
276610115c80Sfei feng - Sun Microsystems - Beijing China break;
276710115c80Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_IPACKETS:
276810115c80Sfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_rx_frags;
276910115c80Sfei feng - Sun Microsystems - Beijing China break;
277010115c80Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_OBYTES:
277110115c80Sfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_tx_bytes;
277210115c80Sfei feng - Sun Microsystems - Beijing China break;
277310115c80Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_OPACKETS:
277410115c80Sfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_tx_frags;
277510115c80Sfei feng - Sun Microsystems - Beijing China break;
277610115c80Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_OERRORS:
277710115c80Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_TX_FAILED:
277810115c80Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_tx_err;
277910115c80Sfei feng - Sun Microsystems - Beijing China break;
278010115c80Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_TX_RETRANS:
278110115c80Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_tx_retries;
278210115c80Sfei feng - Sun Microsystems - Beijing China break;
278310115c80Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_FCS_ERRORS:
278410115c80Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_WEP_ERRORS:
278510115c80Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_TX_FRAGS:
278610115c80Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_MCAST_TX:
278710115c80Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RTS_SUCCESS:
278810115c80Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RTS_FAILURE:
278910115c80Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_ACK_FAILURE:
279010115c80Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RX_FRAGS:
279110115c80Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_MCAST_RX:
279210115c80Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RX_DUPS:
279310115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
279410115c80Sfei feng - Sun Microsystems - Beijing China return (ieee80211_stat(ic, stat, val));
279510115c80Sfei feng - Sun Microsystems - Beijing China default:
279610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
279710115c80Sfei feng - Sun Microsystems - Beijing China return (ENOTSUP);
279810115c80Sfei feng - Sun Microsystems - Beijing China }
279910115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
280010115c80Sfei feng - Sun Microsystems - Beijing China
280110115c80Sfei feng - Sun Microsystems - Beijing China return (0);
280210115c80Sfei feng - Sun Microsystems - Beijing China }
280310115c80Sfei feng - Sun Microsystems - Beijing China
280410115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_attach(dev_info_t * devinfo,ddi_attach_cmd_t cmd)280510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
280610115c80Sfei feng - Sun Microsystems - Beijing China {
280710115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc;
280810115c80Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic;
280910115c80Sfei feng - Sun Microsystems - Beijing China
281010115c80Sfei feng - Sun Microsystems - Beijing China int i, ac, err, ntries, instance;
281110115c80Sfei feng - Sun Microsystems - Beijing China int intr_type, intr_count, intr_actual;
281210115c80Sfei feng - Sun Microsystems - Beijing China char strbuf[32];
281310115c80Sfei feng - Sun Microsystems - Beijing China uint8_t cachelsz;
281410115c80Sfei feng - Sun Microsystems - Beijing China uint16_t command, vendor_id, device_id;
281510115c80Sfei feng - Sun Microsystems - Beijing China uint32_t val;
281610115c80Sfei feng - Sun Microsystems - Beijing China
281710115c80Sfei feng - Sun Microsystems - Beijing China wifi_data_t wd = { 0 };
281810115c80Sfei feng - Sun Microsystems - Beijing China mac_register_t *macp;
281910115c80Sfei feng - Sun Microsystems - Beijing China
282010115c80Sfei feng - Sun Microsystems - Beijing China switch (cmd) {
282110115c80Sfei feng - Sun Microsystems - Beijing China case DDI_ATTACH:
282210115c80Sfei feng - Sun Microsystems - Beijing China break;
282310115c80Sfei feng - Sun Microsystems - Beijing China case DDI_RESUME:
282410115c80Sfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(rt2661_soft_state_p,
282510115c80Sfei feng - Sun Microsystems - Beijing China ddi_get_instance(devinfo));
282610115c80Sfei feng - Sun Microsystems - Beijing China ASSERT(sc != NULL);
282710115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GLOCK(sc);
282810115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_flags &= ~RT2661_F_SUSPEND;
282910115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
283010115c80Sfei feng - Sun Microsystems - Beijing China if (RT2661_IS_RUNNING(sc))
283110115c80Sfei feng - Sun Microsystems - Beijing China (void) rt2661_init(sc);
283210115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
283310115c80Sfei feng - Sun Microsystems - Beijing China "resume now\n");
283410115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
283510115c80Sfei feng - Sun Microsystems - Beijing China default:
283610115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
283710115c80Sfei feng - Sun Microsystems - Beijing China }
283810115c80Sfei feng - Sun Microsystems - Beijing China
283910115c80Sfei feng - Sun Microsystems - Beijing China instance = ddi_get_instance(devinfo);
284010115c80Sfei feng - Sun Microsystems - Beijing China
284110115c80Sfei feng - Sun Microsystems - Beijing China err = ddi_soft_state_zalloc(rt2661_soft_state_p, instance);
284210115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
284310115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
284410115c80Sfei feng - Sun Microsystems - Beijing China "unable to alloc soft_state_p\n");
284510115c80Sfei feng - Sun Microsystems - Beijing China return (err);
284610115c80Sfei feng - Sun Microsystems - Beijing China }
284710115c80Sfei feng - Sun Microsystems - Beijing China
284810115c80Sfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(rt2661_soft_state_p, instance);
284910115c80Sfei feng - Sun Microsystems - Beijing China ic = (struct ieee80211com *)&sc->sc_ic;
285010115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_dev = devinfo;
285110115c80Sfei feng - Sun Microsystems - Beijing China
285210115c80Sfei feng - Sun Microsystems - Beijing China /* PCI configuration */
285310115c80Sfei feng - Sun Microsystems - Beijing China err = ddi_regs_map_setup(devinfo, 0, &sc->sc_cfg_base, 0, 0,
285410115c80Sfei feng - Sun Microsystems - Beijing China &rt2661_csr_accattr, &sc->sc_cfg_handle);
285510115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
285610115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
285710115c80Sfei feng - Sun Microsystems - Beijing China "ddi_regs_map_setup() failed");
285810115c80Sfei feng - Sun Microsystems - Beijing China goto fail1;
285910115c80Sfei feng - Sun Microsystems - Beijing China }
286010115c80Sfei feng - Sun Microsystems - Beijing China
286110115c80Sfei feng - Sun Microsystems - Beijing China cachelsz = ddi_get8(sc->sc_cfg_handle,
286210115c80Sfei feng - Sun Microsystems - Beijing China (uint8_t *)(sc->sc_cfg_base + PCI_CONF_CACHE_LINESZ));
286310115c80Sfei feng - Sun Microsystems - Beijing China if (cachelsz == 0)
286410115c80Sfei feng - Sun Microsystems - Beijing China cachelsz = 0x10;
286510115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_cachelsz = cachelsz << 2;
286610115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_dmabuf_size = roundup(IEEE80211_MAX_LEN, sc->sc_cachelsz);
286710115c80Sfei feng - Sun Microsystems - Beijing China
286810115c80Sfei feng - Sun Microsystems - Beijing China vendor_id = ddi_get16(sc->sc_cfg_handle,
286910115c80Sfei feng - Sun Microsystems - Beijing China (uint16_t *)((uintptr_t)(sc->sc_cfg_base) + PCI_CONF_VENID));
287010115c80Sfei feng - Sun Microsystems - Beijing China device_id = ddi_get16(sc->sc_cfg_handle,
287110115c80Sfei feng - Sun Microsystems - Beijing China (uint16_t *)((uintptr_t)(sc->sc_cfg_base) + PCI_CONF_DEVID));
287210115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
287310115c80Sfei feng - Sun Microsystems - Beijing China "vendor 0x%x, device id 0x%x, cache size %d\n",
287410115c80Sfei feng - Sun Microsystems - Beijing China vendor_id, device_id, cachelsz);
287510115c80Sfei feng - Sun Microsystems - Beijing China
287610115c80Sfei feng - Sun Microsystems - Beijing China /*
287710115c80Sfei feng - Sun Microsystems - Beijing China * Enable response to memory space accesses,
287810115c80Sfei feng - Sun Microsystems - Beijing China * and enabe bus master.
287910115c80Sfei feng - Sun Microsystems - Beijing China */
288010115c80Sfei feng - Sun Microsystems - Beijing China command = PCI_COMM_MAE | PCI_COMM_ME;
288110115c80Sfei feng - Sun Microsystems - Beijing China ddi_put16(sc->sc_cfg_handle,
288210115c80Sfei feng - Sun Microsystems - Beijing China (uint16_t *)((uintptr_t)(sc->sc_cfg_base) + PCI_CONF_COMM),
288310115c80Sfei feng - Sun Microsystems - Beijing China command);
288410115c80Sfei feng - Sun Microsystems - Beijing China ddi_put8(sc->sc_cfg_handle,
288510115c80Sfei feng - Sun Microsystems - Beijing China (uint8_t *)(sc->sc_cfg_base + PCI_CONF_LATENCY_TIMER), 0xa8);
288610115c80Sfei feng - Sun Microsystems - Beijing China ddi_put8(sc->sc_cfg_handle,
288710115c80Sfei feng - Sun Microsystems - Beijing China (uint8_t *)(sc->sc_cfg_base + PCI_CONF_ILINE), 0x10);
288810115c80Sfei feng - Sun Microsystems - Beijing China
288910115c80Sfei feng - Sun Microsystems - Beijing China /* pci i/o space */
289010115c80Sfei feng - Sun Microsystems - Beijing China err = ddi_regs_map_setup(devinfo, 1,
289110115c80Sfei feng - Sun Microsystems - Beijing China &sc->sc_io_base, 0, 0, &rt2661_csr_accattr, &sc->sc_io_handle);
289210115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
289310115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
289410115c80Sfei feng - Sun Microsystems - Beijing China "ddi_regs_map_setup() failed");
289510115c80Sfei feng - Sun Microsystems - Beijing China goto fail2;
289610115c80Sfei feng - Sun Microsystems - Beijing China }
289710115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
289810115c80Sfei feng - Sun Microsystems - Beijing China "PCI configuration is done successfully\n");
289910115c80Sfei feng - Sun Microsystems - Beijing China
290010115c80Sfei feng - Sun Microsystems - Beijing China err = ddi_intr_get_supported_types(devinfo, &intr_type);
290110115c80Sfei feng - Sun Microsystems - Beijing China if ((err != DDI_SUCCESS) || (!(intr_type & DDI_INTR_TYPE_FIXED))) {
290210115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
290310115c80Sfei feng - Sun Microsystems - Beijing China "fixed type interrupt is not supported\n");
290410115c80Sfei feng - Sun Microsystems - Beijing China goto fail3;
290510115c80Sfei feng - Sun Microsystems - Beijing China }
290610115c80Sfei feng - Sun Microsystems - Beijing China
290710115c80Sfei feng - Sun Microsystems - Beijing China err = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_FIXED, &intr_count);
290810115c80Sfei feng - Sun Microsystems - Beijing China if ((err != DDI_SUCCESS) || (intr_count != 1)) {
290910115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
291010115c80Sfei feng - Sun Microsystems - Beijing China "no fixed interrupts\n");
291110115c80Sfei feng - Sun Microsystems - Beijing China goto fail3;
291210115c80Sfei feng - Sun Microsystems - Beijing China }
291310115c80Sfei feng - Sun Microsystems - Beijing China
291410115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_intr_htable = kmem_zalloc(sizeof (ddi_intr_handle_t), KM_SLEEP);
291510115c80Sfei feng - Sun Microsystems - Beijing China
291610115c80Sfei feng - Sun Microsystems - Beijing China err = ddi_intr_alloc(devinfo, sc->sc_intr_htable,
291710115c80Sfei feng - Sun Microsystems - Beijing China DDI_INTR_TYPE_FIXED, 0, intr_count, &intr_actual, 0);
291810115c80Sfei feng - Sun Microsystems - Beijing China if ((err != DDI_SUCCESS) || (intr_actual != 1)) {
291910115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
292010115c80Sfei feng - Sun Microsystems - Beijing China "ddi_intr_alloc() failed 0x%x\n", err);
292110115c80Sfei feng - Sun Microsystems - Beijing China goto faili4;
292210115c80Sfei feng - Sun Microsystems - Beijing China }
292310115c80Sfei feng - Sun Microsystems - Beijing China
292410115c80Sfei feng - Sun Microsystems - Beijing China err = ddi_intr_get_pri(sc->sc_intr_htable[0], &sc->sc_intr_pri);
292510115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
292610115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
292710115c80Sfei feng - Sun Microsystems - Beijing China "ddi_intr_get_pri() failed 0x%x\n", err);
292810115c80Sfei feng - Sun Microsystems - Beijing China goto faili5;
292910115c80Sfei feng - Sun Microsystems - Beijing China }
293010115c80Sfei feng - Sun Microsystems - Beijing China
293110115c80Sfei feng - Sun Microsystems - Beijing China sc->amrr.amrr_min_success_threshold = 1;
293210115c80Sfei feng - Sun Microsystems - Beijing China sc->amrr.amrr_max_success_threshold = 15;
293310115c80Sfei feng - Sun Microsystems - Beijing China
293410115c80Sfei feng - Sun Microsystems - Beijing China /* wait for NIC to initialize */
293510115c80Sfei feng - Sun Microsystems - Beijing China for (ntries = 0; ntries < 1000; ntries++) {
293610115c80Sfei feng - Sun Microsystems - Beijing China if ((val = RT2661_READ(sc, RT2661_MAC_CSR0)) != 0)
293710115c80Sfei feng - Sun Microsystems - Beijing China break;
293810115c80Sfei feng - Sun Microsystems - Beijing China DELAY(1000);
293910115c80Sfei feng - Sun Microsystems - Beijing China }
294010115c80Sfei feng - Sun Microsystems - Beijing China if (ntries == 1000) {
294110115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
294210115c80Sfei feng - Sun Microsystems - Beijing China "timeout waiting for NIC to initialize\n");
294310115c80Sfei feng - Sun Microsystems - Beijing China goto faili5;
294410115c80Sfei feng - Sun Microsystems - Beijing China }
294510115c80Sfei feng - Sun Microsystems - Beijing China
294610115c80Sfei feng - Sun Microsystems - Beijing China /* retrieve RF rev. no and various other things from EEPROM */
294710115c80Sfei feng - Sun Microsystems - Beijing China rt2661_read_eeprom(sc);
294810115c80Sfei feng - Sun Microsystems - Beijing China
294910115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
295010115c80Sfei feng - Sun Microsystems - Beijing China "MAC/BBP RT%X, RF %s\n"
295110115c80Sfei feng - Sun Microsystems - Beijing China "MAC address is: %x:%x:%x:%x:%x:%x\n", val,
295210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_get_rf(sc->rf_rev),
295310115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[0], ic->ic_macaddr[1], ic->ic_macaddr[2],
295410115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[3], ic->ic_macaddr[4], ic->ic_macaddr[5]);
295510115c80Sfei feng - Sun Microsystems - Beijing China
295610115c80Sfei feng - Sun Microsystems - Beijing China /*
295710115c80Sfei feng - Sun Microsystems - Beijing China * Load 8051 microcode into NIC.
295810115c80Sfei feng - Sun Microsystems - Beijing China */
295910115c80Sfei feng - Sun Microsystems - Beijing China switch (device_id) {
296010115c80Sfei feng - Sun Microsystems - Beijing China case 0x0301:
296110115c80Sfei feng - Sun Microsystems - Beijing China ucode = rt2561s_ucode;
296210115c80Sfei feng - Sun Microsystems - Beijing China usize = sizeof (rt2561s_ucode);
296310115c80Sfei feng - Sun Microsystems - Beijing China break;
296410115c80Sfei feng - Sun Microsystems - Beijing China case 0x0302:
296510115c80Sfei feng - Sun Microsystems - Beijing China ucode = rt2561_ucode;
296610115c80Sfei feng - Sun Microsystems - Beijing China usize = sizeof (rt2561_ucode);
296710115c80Sfei feng - Sun Microsystems - Beijing China break;
296810115c80Sfei feng - Sun Microsystems - Beijing China case 0x0401:
296910115c80Sfei feng - Sun Microsystems - Beijing China ucode = rt2661_ucode;
297010115c80Sfei feng - Sun Microsystems - Beijing China usize = sizeof (rt2661_ucode);
297110115c80Sfei feng - Sun Microsystems - Beijing China break;
297210115c80Sfei feng - Sun Microsystems - Beijing China }
297310115c80Sfei feng - Sun Microsystems - Beijing China
297410115c80Sfei feng - Sun Microsystems - Beijing China err = rt2661_load_microcode(sc, ucode, usize);
297510115c80Sfei feng - Sun Microsystems - Beijing China if (err != RT2661_SUCCESS) {
297610115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
297710115c80Sfei feng - Sun Microsystems - Beijing China "could not load 8051 microcode\n");
297810115c80Sfei feng - Sun Microsystems - Beijing China goto faili5;
297910115c80Sfei feng - Sun Microsystems - Beijing China }
298010115c80Sfei feng - Sun Microsystems - Beijing China
298110115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_flags = 0;
298210115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_flags |= RT2661_F_FWLOADED;
298310115c80Sfei feng - Sun Microsystems - Beijing China
298410115c80Sfei feng - Sun Microsystems - Beijing China /*
298510115c80Sfei feng - Sun Microsystems - Beijing China * Allocate Tx and Rx rings.
298610115c80Sfei feng - Sun Microsystems - Beijing China */
298710115c80Sfei feng - Sun Microsystems - Beijing China for (ac = 0; ac < 4; ac++) {
298810115c80Sfei feng - Sun Microsystems - Beijing China err = rt2661_alloc_tx_ring(sc, &sc->txq[ac],
298910115c80Sfei feng - Sun Microsystems - Beijing China RT2661_TX_RING_COUNT);
299010115c80Sfei feng - Sun Microsystems - Beijing China if (err != RT2661_SUCCESS) {
299110115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_attach(): "
299210115c80Sfei feng - Sun Microsystems - Beijing China "could not allocate Tx ring %d\n", ac);
299310115c80Sfei feng - Sun Microsystems - Beijing China goto fail4;
299410115c80Sfei feng - Sun Microsystems - Beijing China }
299510115c80Sfei feng - Sun Microsystems - Beijing China }
299610115c80Sfei feng - Sun Microsystems - Beijing China
299710115c80Sfei feng - Sun Microsystems - Beijing China err = rt2661_alloc_tx_ring(sc, &sc->mgtq, RT2661_MGT_RING_COUNT);
299810115c80Sfei feng - Sun Microsystems - Beijing China if (err != RT2661_SUCCESS) {
299910115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_attach(): "
300010115c80Sfei feng - Sun Microsystems - Beijing China "could not allocate Mgt ring\n");
300110115c80Sfei feng - Sun Microsystems - Beijing China goto fail5;
300210115c80Sfei feng - Sun Microsystems - Beijing China }
300310115c80Sfei feng - Sun Microsystems - Beijing China
300410115c80Sfei feng - Sun Microsystems - Beijing China err = rt2661_alloc_rx_ring(sc, &sc->rxq, RT2661_RX_RING_COUNT);
300510115c80Sfei feng - Sun Microsystems - Beijing China if (err != RT2661_SUCCESS) {
300610115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_attach(): "
300710115c80Sfei feng - Sun Microsystems - Beijing China "could not allocate Rx ring\n");
300810115c80Sfei feng - Sun Microsystems - Beijing China goto fail6;
300910115c80Sfei feng - Sun Microsystems - Beijing China }
301010115c80Sfei feng - Sun Microsystems - Beijing China
301110115c80Sfei feng - Sun Microsystems - Beijing China mutex_init(&sc->sc_genlock, NULL, MUTEX_DRIVER, NULL);
301210115c80Sfei feng - Sun Microsystems - Beijing China mutex_init(&sc->sc_txlock, NULL, MUTEX_DRIVER, NULL);
301310115c80Sfei feng - Sun Microsystems - Beijing China mutex_init(&sc->sc_rxlock, NULL, MUTEX_DRIVER, NULL);
301410115c80Sfei feng - Sun Microsystems - Beijing China
301510115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_phytype = IEEE80211_T_OFDM;
301610115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_opmode = IEEE80211_M_STA;
301710115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_state = IEEE80211_S_INIT;
301810115c80Sfei feng - Sun Microsystems - Beijing China
301910115c80Sfei feng - Sun Microsystems - Beijing China /* set device capabilities */
302010115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_caps =
302110115c80Sfei feng - Sun Microsystems - Beijing China IEEE80211_C_TXPMGT |
302210115c80Sfei feng - Sun Microsystems - Beijing China IEEE80211_C_SHPREAMBLE |
302310115c80Sfei feng - Sun Microsystems - Beijing China IEEE80211_C_SHSLOT;
302410115c80Sfei feng - Sun Microsystems - Beijing China
302510115c80Sfei feng - Sun Microsystems - Beijing China /* WPA/WPA2 support */
302610115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_caps |= IEEE80211_C_WPA;
302710115c80Sfei feng - Sun Microsystems - Beijing China
302810115c80Sfei feng - Sun Microsystems - Beijing China /* set supported .11b and .11g rates */
302910115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_sup_rates[IEEE80211_MODE_11B] = rt2661_rateset_11b;
303010115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_sup_rates[IEEE80211_MODE_11G] = rt2661_rateset_11g;
303110115c80Sfei feng - Sun Microsystems - Beijing China
303210115c80Sfei feng - Sun Microsystems - Beijing China /* set supported .11b and .11g channels (1 through 14) */
303310115c80Sfei feng - Sun Microsystems - Beijing China for (i = 1; i <= 14; i++) {
303410115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_sup_channels[i].ich_freq =
303510115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
303610115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_sup_channels[i].ich_flags =
303710115c80Sfei feng - Sun Microsystems - Beijing China IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
303810115c80Sfei feng - Sun Microsystems - Beijing China IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
303910115c80Sfei feng - Sun Microsystems - Beijing China }
304010115c80Sfei feng - Sun Microsystems - Beijing China
304110115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_maxrssi = 63;
304210115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_xmit = rt2661_mgmt_send;
304310115c80Sfei feng - Sun Microsystems - Beijing China
304410115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_attach(ic);
304510115c80Sfei feng - Sun Microsystems - Beijing China
304610115c80Sfei feng - Sun Microsystems - Beijing China /* register WPA door */
304710115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_register_door(ic, ddi_driver_name(devinfo),
304810115c80Sfei feng - Sun Microsystems - Beijing China ddi_get_instance(devinfo));
304910115c80Sfei feng - Sun Microsystems - Beijing China
305010115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_node_alloc = rt2661_node_alloc;
305110115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_node_free = rt2661_node_free;
305210115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_set_shortslot = rt2661_updateslot;
305310115c80Sfei feng - Sun Microsystems - Beijing China
305410115c80Sfei feng - Sun Microsystems - Beijing China /* override state transition machine */
305510115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_newstate = ic->ic_newstate;
305610115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_newstate = rt2661_newstate;
305710115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_media_init(ic);
305810115c80Sfei feng - Sun Microsystems - Beijing China ic->ic_def_txkey = 0;
305910115c80Sfei feng - Sun Microsystems - Beijing China
306010115c80Sfei feng - Sun Microsystems - Beijing China err = ddi_intr_add_softint(devinfo, &sc->sc_softintr_hdl,
306110115c80Sfei feng - Sun Microsystems - Beijing China DDI_INTR_SOFTPRI_MAX, rt2661_softintr, (caddr_t)sc);
306210115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
306310115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
306410115c80Sfei feng - Sun Microsystems - Beijing China "ddi_add_softintr() failed");
306510115c80Sfei feng - Sun Microsystems - Beijing China goto fail7;
306610115c80Sfei feng - Sun Microsystems - Beijing China }
306710115c80Sfei feng - Sun Microsystems - Beijing China
306810115c80Sfei feng - Sun Microsystems - Beijing China err = ddi_intr_add_handler(sc->sc_intr_htable[0], rt2661_intr,
306910115c80Sfei feng - Sun Microsystems - Beijing China (caddr_t)sc, NULL);
307010115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
307110115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
307210115c80Sfei feng - Sun Microsystems - Beijing China "ddi_intr_addr_handle() failed\n");
307310115c80Sfei feng - Sun Microsystems - Beijing China goto fail8;
307410115c80Sfei feng - Sun Microsystems - Beijing China }
307510115c80Sfei feng - Sun Microsystems - Beijing China
307610115c80Sfei feng - Sun Microsystems - Beijing China err = ddi_intr_enable(sc->sc_intr_htable[0]);
307710115c80Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
307810115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd; rt2661_attach(): "
307910115c80Sfei feng - Sun Microsystems - Beijing China "ddi_intr_enable() failed\n");
308010115c80Sfei feng - Sun Microsystems - Beijing China goto fail9;
308110115c80Sfei feng - Sun Microsystems - Beijing China }
308210115c80Sfei feng - Sun Microsystems - Beijing China
308310115c80Sfei feng - Sun Microsystems - Beijing China /*
308410115c80Sfei feng - Sun Microsystems - Beijing China * Provide initial settings for the WiFi plugin; whenever this
308510115c80Sfei feng - Sun Microsystems - Beijing China * information changes, we need to call mac_plugindata_update()
308610115c80Sfei feng - Sun Microsystems - Beijing China */
308710115c80Sfei feng - Sun Microsystems - Beijing China wd.wd_opmode = ic->ic_opmode;
308810115c80Sfei feng - Sun Microsystems - Beijing China wd.wd_secalloc = WIFI_SEC_NONE;
308910115c80Sfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid);
309010115c80Sfei feng - Sun Microsystems - Beijing China
309110115c80Sfei feng - Sun Microsystems - Beijing China if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
309210115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
309310115c80Sfei feng - Sun Microsystems - Beijing China "MAC version mismatch\n");
309410115c80Sfei feng - Sun Microsystems - Beijing China goto fail10;
309510115c80Sfei feng - Sun Microsystems - Beijing China }
309610115c80Sfei feng - Sun Microsystems - Beijing China
309710115c80Sfei feng - Sun Microsystems - Beijing China macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI;
309810115c80Sfei feng - Sun Microsystems - Beijing China macp->m_driver = sc;
309910115c80Sfei feng - Sun Microsystems - Beijing China macp->m_dip = devinfo;
310010115c80Sfei feng - Sun Microsystems - Beijing China macp->m_src_addr = ic->ic_macaddr;
310110115c80Sfei feng - Sun Microsystems - Beijing China macp->m_callbacks = &rt2661_m_callbacks;
310210115c80Sfei feng - Sun Microsystems - Beijing China macp->m_min_sdu = 0;
310310115c80Sfei feng - Sun Microsystems - Beijing China macp->m_max_sdu = IEEE80211_MTU;
310410115c80Sfei feng - Sun Microsystems - Beijing China macp->m_pdata = &wd;
310510115c80Sfei feng - Sun Microsystems - Beijing China macp->m_pdata_size = sizeof (wd);
310610115c80Sfei feng - Sun Microsystems - Beijing China
310710115c80Sfei feng - Sun Microsystems - Beijing China err = mac_register(macp, &ic->ic_mach);
310810115c80Sfei feng - Sun Microsystems - Beijing China mac_free(macp);
310910115c80Sfei feng - Sun Microsystems - Beijing China if (err != 0) {
311010115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
311110115c80Sfei feng - Sun Microsystems - Beijing China "mac_register err %x\n", err);
311210115c80Sfei feng - Sun Microsystems - Beijing China goto fail10;
311310115c80Sfei feng - Sun Microsystems - Beijing China }
311410115c80Sfei feng - Sun Microsystems - Beijing China
311510115c80Sfei feng - Sun Microsystems - Beijing China /*
311610115c80Sfei feng - Sun Microsystems - Beijing China * Create minor node of type DDI_NT_NET_WIFI
311710115c80Sfei feng - Sun Microsystems - Beijing China */
311810115c80Sfei feng - Sun Microsystems - Beijing China (void) snprintf(strbuf, sizeof (strbuf), "%s%d",
311910115c80Sfei feng - Sun Microsystems - Beijing China "rwd", instance);
312010115c80Sfei feng - Sun Microsystems - Beijing China err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR,
312110115c80Sfei feng - Sun Microsystems - Beijing China instance + 1, DDI_NT_NET_WIFI, 0);
312210115c80Sfei feng - Sun Microsystems - Beijing China
312310115c80Sfei feng - Sun Microsystems - Beijing China /*
312410115c80Sfei feng - Sun Microsystems - Beijing China * Notify link is down now
312510115c80Sfei feng - Sun Microsystems - Beijing China */
312610115c80Sfei feng - Sun Microsystems - Beijing China mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
312710115c80Sfei feng - Sun Microsystems - Beijing China
312810115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
312910115c80Sfei feng - Sun Microsystems - Beijing China "attach successfully\n");
313010115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
313110115c80Sfei feng - Sun Microsystems - Beijing China
313210115c80Sfei feng - Sun Microsystems - Beijing China fail10:
313310115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_disable(sc->sc_intr_htable[0]);
313410115c80Sfei feng - Sun Microsystems - Beijing China fail9:
313510115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_remove_handler(sc->sc_intr_htable[0]);
313610115c80Sfei feng - Sun Microsystems - Beijing China fail8:
313710115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_remove_softint(sc->sc_softintr_hdl);
313810115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_softintr_hdl = NULL;
313910115c80Sfei feng - Sun Microsystems - Beijing China fail7:
314010115c80Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_genlock);
314110115c80Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_txlock);
314210115c80Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_rxlock);
314310115c80Sfei feng - Sun Microsystems - Beijing China fail6:
314410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_rx_ring(sc, &sc->rxq);
314510115c80Sfei feng - Sun Microsystems - Beijing China fail5:
314610115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_tx_ring(sc, &sc->mgtq);
314710115c80Sfei feng - Sun Microsystems - Beijing China fail4:
314810115c80Sfei feng - Sun Microsystems - Beijing China while (--ac >= 0)
314910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_tx_ring(sc, &sc->txq[ac]);
315010115c80Sfei feng - Sun Microsystems - Beijing China faili5:
315110115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_free(sc->sc_intr_htable[0]);
315210115c80Sfei feng - Sun Microsystems - Beijing China faili4:
315310115c80Sfei feng - Sun Microsystems - Beijing China kmem_free(sc->sc_intr_htable, sizeof (ddi_intr_handle_t));
315410115c80Sfei feng - Sun Microsystems - Beijing China fail3:
315510115c80Sfei feng - Sun Microsystems - Beijing China ddi_regs_map_free(&sc->sc_io_handle);
315610115c80Sfei feng - Sun Microsystems - Beijing China fail2:
315710115c80Sfei feng - Sun Microsystems - Beijing China ddi_regs_map_free(&sc->sc_cfg_handle);
315810115c80Sfei feng - Sun Microsystems - Beijing China fail1:
315910115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
316010115c80Sfei feng - Sun Microsystems - Beijing China }
316110115c80Sfei feng - Sun Microsystems - Beijing China
316210115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_detach(dev_info_t * devinfo,ddi_detach_cmd_t cmd)316310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
316410115c80Sfei feng - Sun Microsystems - Beijing China {
316510115c80Sfei feng - Sun Microsystems - Beijing China
316610115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc;
316710115c80Sfei feng - Sun Microsystems - Beijing China
316810115c80Sfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(rt2661_soft_state_p, ddi_get_instance(devinfo));
316910115c80Sfei feng - Sun Microsystems - Beijing China
317010115c80Sfei feng - Sun Microsystems - Beijing China switch (cmd) {
317110115c80Sfei feng - Sun Microsystems - Beijing China case DDI_DETACH:
317210115c80Sfei feng - Sun Microsystems - Beijing China break;
317310115c80Sfei feng - Sun Microsystems - Beijing China case DDI_SUSPEND:
317410115c80Sfei feng - Sun Microsystems - Beijing China if (RT2661_IS_RUNNING(sc))
317510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_stop(sc);
317610115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GLOCK(sc);
317710115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_flags |= RT2661_F_SUSPEND;
317810115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_flags &= ~RT2661_F_FWLOADED;
317910115c80Sfei feng - Sun Microsystems - Beijing China RT2661_GUNLOCK(sc);
318010115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_detach(): "
318110115c80Sfei feng - Sun Microsystems - Beijing China "suspend now\n");
318210115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
318310115c80Sfei feng - Sun Microsystems - Beijing China default:
318410115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
318510115c80Sfei feng - Sun Microsystems - Beijing China }
318610115c80Sfei feng - Sun Microsystems - Beijing China
318710115c80Sfei feng - Sun Microsystems - Beijing China if (mac_disable(sc->sc_ic.ic_mach) != 0)
318810115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
318910115c80Sfei feng - Sun Microsystems - Beijing China
319010115c80Sfei feng - Sun Microsystems - Beijing China /*
319110115c80Sfei feng - Sun Microsystems - Beijing China * Unregister from the MAC layer subsystem
319210115c80Sfei feng - Sun Microsystems - Beijing China */
319310115c80Sfei feng - Sun Microsystems - Beijing China (void) mac_unregister(sc->sc_ic.ic_mach);
319410115c80Sfei feng - Sun Microsystems - Beijing China
319510115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_remove_softint(sc->sc_softintr_hdl);
319610115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_softintr_hdl = NULL;
319710115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_disable(sc->sc_intr_htable[0]);
319810115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_remove_handler(sc->sc_intr_htable[0]);
319910115c80Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_free(sc->sc_intr_htable[0]);
320010115c80Sfei feng - Sun Microsystems - Beijing China kmem_free(sc->sc_intr_htable, sizeof (ddi_intr_handle_t));
320110115c80Sfei feng - Sun Microsystems - Beijing China
320210115c80Sfei feng - Sun Microsystems - Beijing China /*
320310115c80Sfei feng - Sun Microsystems - Beijing China * detach ieee80211 layer
320410115c80Sfei feng - Sun Microsystems - Beijing China */
320510115c80Sfei feng - Sun Microsystems - Beijing China ieee80211_detach(&sc->sc_ic);
320610115c80Sfei feng - Sun Microsystems - Beijing China
320710115c80Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_genlock);
320810115c80Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_txlock);
320910115c80Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_rxlock);
321010115c80Sfei feng - Sun Microsystems - Beijing China
321110115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_tx_ring(sc, &sc->txq[0]);
321210115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_tx_ring(sc, &sc->txq[1]);
321310115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_tx_ring(sc, &sc->txq[2]);
321410115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_tx_ring(sc, &sc->txq[3]);
321510115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_tx_ring(sc, &sc->mgtq);
321610115c80Sfei feng - Sun Microsystems - Beijing China rt2661_free_rx_ring(sc, &sc->rxq);
321710115c80Sfei feng - Sun Microsystems - Beijing China
321810115c80Sfei feng - Sun Microsystems - Beijing China ddi_regs_map_free(&sc->sc_io_handle);
321910115c80Sfei feng - Sun Microsystems - Beijing China ddi_regs_map_free(&sc->sc_cfg_handle);
322010115c80Sfei feng - Sun Microsystems - Beijing China
322110115c80Sfei feng - Sun Microsystems - Beijing China ddi_remove_minor_node(devinfo, NULL);
322210115c80Sfei feng - Sun Microsystems - Beijing China ddi_soft_state_free(rt2661_soft_state_p, ddi_get_instance(devinfo));
322310115c80Sfei feng - Sun Microsystems - Beijing China
322410115c80Sfei feng - Sun Microsystems - Beijing China RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_detach(): "
322510115c80Sfei feng - Sun Microsystems - Beijing China "detach successfully\n");
322610115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
322710115c80Sfei feng - Sun Microsystems - Beijing China }
322810115c80Sfei feng - Sun Microsystems - Beijing China
322910115c80Sfei feng - Sun Microsystems - Beijing China static int
rt2661_quiesce(dev_info_t * dip)323010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_quiesce(dev_info_t *dip)
323110115c80Sfei feng - Sun Microsystems - Beijing China {
323210115c80Sfei feng - Sun Microsystems - Beijing China struct rt2661_softc *sc;
323310115c80Sfei feng - Sun Microsystems - Beijing China
323410115c80Sfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(rt2661_soft_state_p, ddi_get_instance(dip));
323510115c80Sfei feng - Sun Microsystems - Beijing China if (sc == NULL)
323610115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
323710115c80Sfei feng - Sun Microsystems - Beijing China
323810115c80Sfei feng - Sun Microsystems - Beijing China #ifdef DEBUG
323910115c80Sfei feng - Sun Microsystems - Beijing China rt2661_dbg_flags = 0;
324010115c80Sfei feng - Sun Microsystems - Beijing China #endif
324110115c80Sfei feng - Sun Microsystems - Beijing China
324210115c80Sfei feng - Sun Microsystems - Beijing China /*
324310115c80Sfei feng - Sun Microsystems - Beijing China * No more blocking is allowed while we are in quiesce(9E) entry point
324410115c80Sfei feng - Sun Microsystems - Beijing China */
324510115c80Sfei feng - Sun Microsystems - Beijing China sc->sc_flags |= RT2661_F_QUIESCE;
324610115c80Sfei feng - Sun Microsystems - Beijing China
324710115c80Sfei feng - Sun Microsystems - Beijing China /*
324810115c80Sfei feng - Sun Microsystems - Beijing China * Disable all interrupts
324910115c80Sfei feng - Sun Microsystems - Beijing China */
325010115c80Sfei feng - Sun Microsystems - Beijing China rt2661_stop(sc);
325110115c80Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
325210115c80Sfei feng - Sun Microsystems - Beijing China }
325310115c80Sfei feng - Sun Microsystems - Beijing China
325410115c80Sfei feng - Sun Microsystems - Beijing China int
_info(struct modinfo * modinfop)325510115c80Sfei feng - Sun Microsystems - Beijing China _info(struct modinfo *modinfop)
325610115c80Sfei feng - Sun Microsystems - Beijing China {
325710115c80Sfei feng - Sun Microsystems - Beijing China return (mod_info(&modlinkage, modinfop));
325810115c80Sfei feng - Sun Microsystems - Beijing China }
325910115c80Sfei feng - Sun Microsystems - Beijing China
326010115c80Sfei feng - Sun Microsystems - Beijing China int
_init(void)326110115c80Sfei feng - Sun Microsystems - Beijing China _init(void)
326210115c80Sfei feng - Sun Microsystems - Beijing China {
326310115c80Sfei feng - Sun Microsystems - Beijing China int status;
326410115c80Sfei feng - Sun Microsystems - Beijing China
326510115c80Sfei feng - Sun Microsystems - Beijing China status = ddi_soft_state_init(&rt2661_soft_state_p,
326610115c80Sfei feng - Sun Microsystems - Beijing China sizeof (struct rt2661_softc), 1);
326710115c80Sfei feng - Sun Microsystems - Beijing China if (status != 0)
326810115c80Sfei feng - Sun Microsystems - Beijing China return (status);
326910115c80Sfei feng - Sun Microsystems - Beijing China
327010115c80Sfei feng - Sun Microsystems - Beijing China mac_init_ops(&rwd_dev_ops, "rwd");
327110115c80Sfei feng - Sun Microsystems - Beijing China status = mod_install(&modlinkage);
327210115c80Sfei feng - Sun Microsystems - Beijing China if (status != 0) {
327310115c80Sfei feng - Sun Microsystems - Beijing China mac_fini_ops(&rwd_dev_ops);
327410115c80Sfei feng - Sun Microsystems - Beijing China ddi_soft_state_fini(&rt2661_soft_state_p);
327510115c80Sfei feng - Sun Microsystems - Beijing China }
327610115c80Sfei feng - Sun Microsystems - Beijing China return (status);
327710115c80Sfei feng - Sun Microsystems - Beijing China }
327810115c80Sfei feng - Sun Microsystems - Beijing China
327910115c80Sfei feng - Sun Microsystems - Beijing China int
_fini(void)328010115c80Sfei feng - Sun Microsystems - Beijing China _fini(void)
328110115c80Sfei feng - Sun Microsystems - Beijing China {
328210115c80Sfei feng - Sun Microsystems - Beijing China int status;
328310115c80Sfei feng - Sun Microsystems - Beijing China
328410115c80Sfei feng - Sun Microsystems - Beijing China status = mod_remove(&modlinkage);
328510115c80Sfei feng - Sun Microsystems - Beijing China if (status == 0) {
328610115c80Sfei feng - Sun Microsystems - Beijing China mac_fini_ops(&rwd_dev_ops);
328710115c80Sfei feng - Sun Microsystems - Beijing China ddi_soft_state_fini(&rt2661_soft_state_p);
328810115c80Sfei feng - Sun Microsystems - Beijing China }
328910115c80Sfei feng - Sun Microsystems - Beijing China return (status);
329010115c80Sfei feng - Sun Microsystems - Beijing China }
3291