rt2560.c revision 5644143a6cf1e70bc2e78d5140970830aae0e8cd
fb91fd8a302dfb13e250bbefb6a3970c2edc3ae3zf * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Use is subject to license terms.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Copyright (c) 2005, 2006
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Damien Bergamini <damien.bergamini@free.fr>
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Permission to use, copy, modify, and distribute this software for any
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * purpose with or without fee is hereby granted, provided that the above
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * copyright notice and this permission notice appear in all copies.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Ralink Technology RT2560 chipset driver
e07d9cb85217949d497b02d7211de8a197d2f2ebzf/* quickly determine if a given rate is CCK or OFDM */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf#define RAL_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Supported rates for 802.11a/b/g modes (in 500Kbps unit).
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const struct ieee80211_rateset rt2560_rateset_11a =
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const struct ieee80211_rateset rt2560_rateset_11b =
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const struct ieee80211_rateset rt2560_rateset_11g =
e07d9cb85217949d497b02d7211de8a197d2f2ebzf { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const struct {
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const struct {
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const uint32_t rt2560_rf2522_r2[] = RT2560_RF2522_R2;
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const uint32_t rt2560_rf2523_r2[] = RT2560_RF2523_R2;
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const uint32_t rt2560_rf2524_r2[] = RT2560_RF2524_R2;
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const uint32_t rt2560_rf2525_r2[] = RT2560_RF2525_R2;
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const uint32_t rt2560_rf2525_hi_r2[] = RT2560_RF2525_HI_R2;
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const uint32_t rt2560_rf2525e_r2[] = RT2560_RF2525E_R2;
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const uint32_t rt2560_rf2526_r2[] = RT2560_RF2526_R2;
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const uint32_t rt2560_rf2526_hi_r2[] = RT2560_RF2526_HI_R2;
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const struct {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * PIO access attributes for registers
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * DMA access attributes for descriptors: NOT to be byte swapped.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Describes the chip's DMA engine
e07d9cb85217949d497b02d7211de8a197d2f2ebzf 0 /* dma_attr_flags */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * device operations
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Module Loading Data & Entry Points
e07d9cb85217949d497b02d7211de8a197d2f2ebzfDDI_DEFINE_STREAM_OPS(ral_dev_ops, nulldev, nulldev, rt2560_attach,
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang rt2560_detach, nodev, NULL, D_MP, NULL, rt2560_quiesce);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf &mod_driverops, /* Type of module. This one is a driver */
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang "Ralink RT2500 driver v1.5", /* short description */
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic int rt2560_m_start(void *);
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void rt2560_m_stop(void *);
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic int rt2560_m_multicst(void *, boolean_t, const uint8_t *);
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fangstatic int rt2560_m_setprop(void *, const char *, mac_prop_id_t,
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang uint_t, const void *);
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fangstatic int rt2560_m_getprop(void *, const char *, mac_prop_id_t,
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* update basic rate set */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* 11b basic rates: 1, 2Mbps */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* 11a basic rates: 6, 12, 24Mbps */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_update_led(struct rt2560_softc *sc, int led1, int led2)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* set ON period to 70ms and OFF period to 30ms */
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_HW, "setting BSSID to " MACSTR "\n", MAC2STR(bssid));
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_bbp_write(struct rt2560_softc *sc, uint8_t reg, uint8_t val)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf tmp = RT2560_BBP_WRITE | RT2560_BBP_BUSY | reg << 8 | val;
e07d9cb85217949d497b02d7211de8a197d2f2ebzf return (0);
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_rf_write(struct rt2560_softc *sc, uint8_t reg, uint32_t val)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf tmp = RT2560_RF_BUSY | RT2560_RF_20BIT | (val & 0xfffff) << 2 |
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* remember last written value in sc */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_HW, "RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff);
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* adjust txpower using ifconfig settings */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_CHAN, "setting channel to %u, txpower to %u\n",
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF2, rt2560_rf2522_r2[chan - 1]);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF2, rt2560_rf2523_r2[chan - 1]);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF2, rt2560_rf2524_r2[chan - 1]);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF2, rt2560_rf2525_hi_r2[chan - 1]);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF2, rt2560_rf2525_r2[chan - 1]);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF2, rt2560_rf2525e_r2[chan - 1]);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00286 : 0x00282);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF2, rt2560_rf2526_hi_r2[chan - 1]);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF2, rt2560_rf2526_r2[chan - 1]);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rt2560_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* dual-band RF */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* set Japan filter bit for channel 14 */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* clear CRC errors */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Refer to IEEE Std 802.11-1999 pp. 123 for more information on TSF
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * synchronization.
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* first, disable TSF synchronization */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf preload = (ic->ic_opmode == IEEE80211_M_STA) ? 384 : 1024;
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* finally, enable TSF synchronization */
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* no short preamble for 1Mbps */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* values taken from the reference driver */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* same values as above or'ed 0x8 */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? "short" : "long");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * This function can be called by ieee80211_set_shortslottime(). Refer to
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * IEEE Std 802.11-1999 pp. 85 to know how these values are computed.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* update the MAC slot boundaries */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf eifs = (ic->ic_curmode == IEEE80211_MODE_11B) ? 364 : 60;
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_HW, "setting slottime to %uus\n", slottime);
e07d9cb85217949d497b02d7211de8a197d2f2ebzfral_dma_region_alloc(struct rt2560_softc *sc, struct dma_region *dr,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_DMA, "ral_dma_region_alloc() size=%u\n", size);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf err = ddi_dma_alloc_handle(dip, &ral_dma_attr, DDI_DMA_SLEEP, NULL,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf err = ddi_dma_mem_alloc(dr->dr_hnd, size, &ral_desc_accattr,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf bind_flags, DDI_DMA_SLEEP, NULL, &dr->dr_cookie, &dr->dr_ccnt);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_DMA, "get physical-base=0x%08x\n", dr->dr_pbase);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf/* ARGSUSED */
e07d9cb85217949d497b02d7211de8a197d2f2ebzfral_dma_region_free(struct rt2560_softc *sc, struct dma_region *dr)
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_alloc_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ring->data = kmem_zalloc(count * (sizeof (struct rt2560_tx_data)),
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ring->dr_txbuf = kmem_zalloc(count * (sizeof (struct dma_region)),
e07d9cb85217949d497b02d7211de8a197d2f2ebzf for (i = 0; i < count; i++) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf while (i >= 0) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ring->desc = (struct rt2560_tx_desc *)ring->dr_desc.dr_base;
e07d9cb85217949d497b02d7211de8a197d2f2ebzf for (i = 0; i < count; i++) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ring->desc[i].physaddr = LE_32(ring->dr_txbuf[i].dr_pbase);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf/* ARGSUSED */
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_reset_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ring->count * sizeof (struct rt2560_tx_desc), DDI_DMA_SYNC_FORDEV);
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_free_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* tx buf */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf kmem_free(ring->data, ring->count * (sizeof (struct rt2560_tx_data)));
e07d9cb85217949d497b02d7211de8a197d2f2ebzf kmem_free(ring->dr_txbuf, ring->count * (sizeof (struct dma_region)));
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* setup tx rings */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* rings must be initialized in this exact order */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* setup rx ring */
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_alloc_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ring->data = kmem_zalloc(count * (sizeof (struct rt2560_rx_data)),
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ring->dr_rxbuf = kmem_zalloc(count * (sizeof (struct dma_region)),
e07d9cb85217949d497b02d7211de8a197d2f2ebzf for (i = 0; i < count; i++) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf while (i >= 0) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ring->desc = (struct rt2560_rx_desc *)ring->dr_desc.dr_base;
e07d9cb85217949d497b02d7211de8a197d2f2ebzf for (i = 0; i < count; i++) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf/* ARGSUSED */
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_reset_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring)
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_free_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* rx buf */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf kmem_free(ring->data, ring->count * (sizeof (struct rt2560_rx_data)));
e07d9cb85217949d497b02d7211de8a197d2f2ebzf kmem_free(ring->dr_rxbuf, ring->count * (sizeof (struct dma_region)));
e07d9cb85217949d497b02d7211de8a197d2f2ebzf/* ARGSUSED */
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic struct ieee80211_node *
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * This function is called periodically (every 200ms) during scanning to
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * switch from one channel to another.
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * This function is called for each node present in the node station table.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf/* ARGSUSED */
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * This function is called periodically (every 100ms) in RUN state to update
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * the rate adaptation statistics.
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ieee80211_iterate_nodes(&ic->ic_sta, rt2560_iter_func, arg);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf sc->sc_rssadapt_id = timeout(rt2560_update_rssadapt, (void *)sc,
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf switch (nstate) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* abort TSF synchronization */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* turn association led off */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* turn assocation led on */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Finally, start any timers.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Read 16 bits at address 'addr' from the serial EEPROM (either 93C46 or
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* clock C once before the first command */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* write start bit (1) */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* write READ opcode (10) */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* write address (A5-A0 or A7-A0) */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf for (; n >= 0; n--) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* read data Q15-Q0 */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf for (n = 15; n >= 0; n--) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* clear Chip Select and clock C */
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf (void) ddi_dma_sync(dr->dr_hnd, 0, count * RT2560_TX_DESC_SIZE,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf for (;;) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf "data frame sent after %u retries\n",
e07d9cb85217949d497b02d7211de8a197d2f2ebzf "sending data frame failed (too much retries)\n");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* descriptor is no longer valid */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_INTR, "tx done idx=%u\n", sc->txq.next);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf sc->txq.next = (sc->txq.next + 1) % RT2560_TX_RING_COUNT;
e07d9cb85217949d497b02d7211de8a197d2f2ebzf (void) ddi_dma_sync(dr->dr_hnd, 0, count * RT2560_TX_DESC_SIZE,
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf (void) ddi_dma_sync(dr->dr_hnd, 0, count * RT2560_TX_DESC_SIZE,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf for (;;) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf "mgt frame sent after %u retries\n",
e07d9cb85217949d497b02d7211de8a197d2f2ebzf "sending mgt frame failed (too much " "retries)\n");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* descriptor is no longer valid */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_INTR, "prio done idx=%u\n", sc->prioq.next);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf sc->prioq.next = (sc->prioq.next + 1) % RT2560_PRIO_RING_COUNT;
e07d9cb85217949d497b02d7211de8a197d2f2ebzf (void) ddi_dma_sync(dr->dr_hnd, 0, count * RT2560_TX_DESC_SIZE,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Some frames were received. Pass them to the hardware cipher engine before
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * sending them to the 802.11 layer.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf (void) ddi_dma_sync(dr->dr_hnd, 0, count * RT2560_RX_DESC_SIZE,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf for (;;) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * This should not happen since we did not request
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * to receive those frames when we filled RXCSR0.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (((LE_32(desc->flags) >> 16) & 0xfff) > RAL_RXBUF_SIZE) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf " allocate mblk failed.\n");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* give rssi to the rate adatation algorithm */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* send the frame to the 802.11 layer */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* node is no longer needed */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf (void) ddi_dma_sync(dr->dr_hnd, 0, count * RT2560_TX_DESC_SIZE,
ff3124eff995e6cd8ebd8c6543648e0670920034ff /* LINTED E_BAD_PTR_CAST_ALIGN */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Check if the soft interrupt is triggered by another
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * driver at the same level.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Return the expected ack rate for a frame transmitted at rate `rate'.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * XXX: this should depend on the destination node basic rate set.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf switch (rate) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* CCK rates */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf return (2);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf return ((ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* OFDM rates */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf return (12);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf return (24);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf return (48);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* default to 1Mbps */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf return (2);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * The function automatically determines the operating mode depending on the
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * given rate. `flags' indicates whether short preamble is in use or not.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* IEEE Std 802.11a-1999, pp. 37 */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* IEEE Std 802.11b-1999, pp. 28 */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf switch (rate) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* CCK rates (returned values are device-dependent) */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* unsupported rates (should not get there) */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf default: return (0xff);
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_setup_tx_desc(struct rt2560_softc *sc, struct rt2560_tx_desc *desc,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* setup PLCP fields */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
e07d9cb85217949d497b02d7211de8a197d2f2ebzf/* ARGSUSED */
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_mgmt_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (m == NULL) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_TX, "rt2560_mgmt_send: can't alloc mblk.\n");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* to support shared_key auth mode */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (k == NULL) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* packet header may have moved, reset our local pointer */
ff3124eff995e6cd8ebd8c6543648e0670920034ff /* LINTED E_BAD_PTR_CAST_ALIGN */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* tell hardware to add timestamp for probe responses */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf (void) ddi_dma_sync(dr->dr_hnd, 0, RAL_TXBUF_SIZE, DDI_DMA_SYNC_FORDEV);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf (void) ddi_dma_sync(dr->dr_hnd, idx * RT2560_TX_DESC_SIZE,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_MGMT, "sending mgt frame len=%u idx=%u rate=%u\n",
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* kick prio */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf sc->prioq.queued++; /* IF > RT2560_PRIO_RING_COUNT? FULL */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf sc->prioq.cur = (sc->prioq.cur + 1) % RT2560_PRIO_RING_COUNT;
e07d9cb85217949d497b02d7211de8a197d2f2ebzf "no TX DMA buffer available!\n");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (m == NULL) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_TX, "rt2560_xmit(): can't alloc mblk.\n");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (k == NULL) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* packet header may have moved, reset our local pointer */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * RTS/CTS exchange ignore, since the max packet will less than
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * the rtsthreshold (2346)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Unnecessary codes deleted.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ni->in_txrate = ral_rssadapt_choose(&rn->rssadapt, rs, wh,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (rate <= 0) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* remember link conditions for rate adaptation algorithm */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf dur = rt2560_txtime(RAL_ACK_SIZE, rt2560_ack_rate(ic, rate),
ff3124eff995e6cd8ebd8c6543648e0670920034ff /* LINTED E_BAD_PTR_CAST_ALIGN */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* flags |= RT2560_TX_CIPHER_NONE; */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf (void) ddi_dma_sync(dr->dr_hnd, 0, RAL_TXBUF_SIZE, DDI_DMA_SYNC_FORDEV);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf (void) ddi_dma_sync(dr->dr_hnd, idx * RT2560_TX_DESC_SIZE,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_TX, "sending data frame len=%u idx=%u rate=%u\n",
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* kick tx */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * No data frames go out unless we're associated; this
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * should not happen as the 802.11 layer does not enable
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * the xmit queue until we enter the RUN state.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf return (mp);
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_set_macaddr(struct rt2560_softc *sc, uint8_t *addr)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_get_macaddr(struct rt2560_softc *sc, uint8_t *addr)
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf (sc->sc_rcr & RAL_RCR_PROMISC) ? "entering" : "leaving");
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic const char *
e07d9cb85217949d497b02d7211de8a197d2f2ebzf switch (rev) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf default: return ("unknown");
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* read default values for BBP registers */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf for (i = 0; i < 16; i++) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf val = rt2560_eeprom_read(sc, RT2560_EEPROM_BBP_BASE + i);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* read Tx power for all b/g channels */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf#define N(a) (sizeof (a) / sizeof ((a)[0]))
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* wait for BBP to be ready */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* initialize BBP registers to default values */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf for (i = 0; i < N(rt2560_def_bbp); i++) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf return (0);
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_set_txantenna(struct rt2560_softc *sc, int antenna)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf tx = rt2560_bbp_read(sc, RT2560_BBP_TX) & ~RT2560_BBP_ANTMASK;
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* need to force I/Q flip for RF 2525e, 2526 and 5222 */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (sc->rf_rev == RT2560_RF_2525E || sc->rf_rev == RT2560_RF_2526 ||
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* update values for CCK and OFDM in BBPCSR1 */
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_set_rxantenna(struct rt2560_softc *sc, int antenna)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf rx = rt2560_bbp_read(sc, RT2560_BBP_RX) & ~RT2560_BBP_ANTMASK;
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* need to force no I/Q flip for RF 2525e and 2526 */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (sc->rf_rev == RT2560_RF_2525E || sc->rf_rev == RT2560_RF_2526)
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* abort Tx */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* disable Rx */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* reset ASIC (imply reset BBP) */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* disable interrupts */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* reset Tx and Rx rings */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf#define N(a) (sizeof (a) / sizeof ((a)[0]))
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* struct rt2560_softc *sc = priv; */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* setup tx/rx ring */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* initialize MAC registers to default values */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf for (i = 0; i < N(rt2560_def_mac); i++)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_WRITE(sc, rt2560_def_mac[i].reg, rt2560_def_mac[i].val);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* set basic rate set (will be updated later) */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* set default BSS channel */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* kick Rx */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* clear old FCS and Rx FIFO errors */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* clear any pending interrupts */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* enable interrupts */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf type = crypto_mech2id(SUN_CKM_RC4); /* load rc4 module into kernel */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_GLD, "enter rt2560_m_start(%d)\n", type);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * initialize rt2560 hardware
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_GLD, "rt2560_m_unicst(): " MACSTR "\n",
e07d9cb85217949d497b02d7211de8a197d2f2ebzf return (0);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf/*ARGSUSED*/
e07d9cb85217949d497b02d7211de8a197d2f2ebzfrt2560_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
e07d9cb85217949d497b02d7211de8a197d2f2ebzf return (0);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf return (0);
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang * callback functions for /get/set properties
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fangrt2560_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang err = ieee80211_setprop(ic, pr_name, wldp_pr_num,
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang (void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fangrt2560_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang uint_t pr_flags, uint_t wldp_length, void *wldp_buf)
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num,
e07d9cb85217949d497b02d7211de8a197d2f2ebzfstatic void
e07d9cb85217949d497b02d7211de8a197d2f2ebzf switch (stat) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
e07d9cb85217949d497b02d7211de8a197d2f2ebzf return (0);
ff3124eff995e6cd8ebd8c6543648e0670920034ff /* LINTED E_BAD_PTR_CAST_ALIGN */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (r == 0xffffffff) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (!(r & RT2560_INTR_ALL)) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* disable interrupts */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* re-enable interrupts */
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang * quiesce(9E) entry point.
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang * This function is called when the system is single-threaded at high
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang * PIL with preemption disabled. Therefore, this function must not be
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang * DDI_FAILURE indicates an error condition and should almost never happen.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf sc = ddi_get_soft_state(ral_soft_state_p, ddi_get_instance(devinfo));
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* abort Tx */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* disable Rx */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* reset ASIC (imply reset BBP) */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* disable interrupts */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (ddi_soft_state_zalloc(ral_soft_state_p, instance) != DDI_SUCCESS) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf "unable to alloc soft_state_p\n");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* pci configuration */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf err = ddi_regs_map_setup(devinfo, 0, ®s, 0, 0, &ral_csr_accattr,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf "ddi_regs_map_setup() failed");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf cachelsz = ddi_get8(ioh, (uint8_t *)(regs + PCI_CONF_CACHE_LINESZ));
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_GLD, "ral: rt2560_attach(): vendor 0x%x, "
e07d9cb85217949d497b02d7211de8a197d2f2ebzf "device id 0x%x, cache size %d\n", vendor_id, device_id, cachelsz);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Enable response to memory space accesses,
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * and enabe bus master.
ff3124eff995e6cd8ebd8c6543648e0670920034ff ddi_put16(ioh, (uint16_t *)((uintptr_t)regs + PCI_CONF_COMM), command);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ddi_put8(ioh, (uint8_t *)(regs + PCI_CONF_LATENCY_TIMER), 0xa8);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* pci i/o space */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf "ddi_regs_map_setup() failed");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* initialize the ral rate */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* retrieve RT2560 rev. no */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* retrieve MAC address */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* retrieve RF rev. no and various other things from EEPROM */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_GLD, "MAC/BBP RT2560 (rev 0x%02x), RF %s\n",
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Allocate Tx and Rx rings.
e07d9cb85217949d497b02d7211de8a197d2f2ebzf err = rt2560_alloc_tx_ring(sc, &sc->txq, RT2560_TX_RING_COUNT);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf err = rt2560_alloc_tx_ring(sc, &sc->prioq, RT2560_PRIO_RING_COUNT);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_GLD, "could not allocate Prio ring\n");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf err = rt2560_alloc_rx_ring(sc, &sc->rxq, RT2560_RX_RING_COUNT);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf mutex_init(&sc->prioq.tx_lock, NULL, MUTEX_DRIVER, NULL);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* set device capabilities */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* set supported .11a rates */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ic->ic_sup_rates[IEEE80211_MODE_11A] = rt2560_rateset_11a;
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* set supported .11a channels */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* set supported .11b and .11g rates */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ic->ic_sup_rates[IEEE80211_MODE_11B] = rt2560_rateset_11b;
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ic->ic_sup_rates[IEEE80211_MODE_11G] = rt2560_rateset_11g;
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* set supported .11b and .11g channels (1 through 14) */
3a1a8936dac0ebe7e956fa122b0b0d15e62d4108zf /* register WPA door */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf /* override state transition machine */
e07d9cb85217949d497b02d7211de8a197d2f2ebzf &sc->sc_softint_id, NULL, 0, ral_softint_handler, (caddr_t)sc);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf "ddi_add_softintr() failed");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf "Can not get iblock cookie for INT\n");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf err = ddi_add_intr(devinfo, 0, NULL, NULL, rt2560_intr, (caddr_t)sc);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf "unable to add device interrupt handler\n");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Provide initial settings for the WiFi plugin; whenever this
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * information changes, we need to call mac_plugindata_update()
e07d9cb85217949d497b02d7211de8a197d2f2ebzf "MAC version mismatch\n");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (err != 0) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Create minor node of type DDI_NT_NET_WIFI
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_GLD, "ddi_create_minor_node() failed\n");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Notify link is down now
e07d9cb85217949d497b02d7211de8a197d2f2ebzf RAL_DEBUG(RAL_DBG_GLD, "rt2560_attach() exit successfully.\n");
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ddi_soft_state_free(ral_soft_state_p, ddi_get_instance(devinfo));
e07d9cb85217949d497b02d7211de8a197d2f2ebzf sc = ddi_get_soft_state(ral_soft_state_p, ddi_get_instance(devinfo));
42516a0c6ebf6e259c2abcd1ca315fec43268f39xinghua wen - Sun Microsystems - Beijing China if (mac_disable(sc->sc_ic.ic_mach) != 0)
42516a0c6ebf6e259c2abcd1ca315fec43268f39xinghua wen - Sun Microsystems - Beijing China return (DDI_FAILURE);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * Unregister from the MAC layer subsystem
42516a0c6ebf6e259c2abcd1ca315fec43268f39xinghua wen - Sun Microsystems - Beijing China (void) mac_unregister(sc->sc_ic.ic_mach);
e07d9cb85217949d497b02d7211de8a197d2f2ebzf * detach ieee80211 layer
e07d9cb85217949d497b02d7211de8a197d2f2ebzf ddi_soft_state_free(ral_soft_state_p, ddi_get_instance(devinfo));
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (status != 0) {
e07d9cb85217949d497b02d7211de8a197d2f2ebzf if (status == 0) {