ural.c revision 5644143a6cf1e70bc2e78d5140970830aae0e8cd
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2005, 2006
* Damien Bergamini <damien.bergamini@free.fr>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Ralink Technology RT2500USB chipset driver
*/
#include <sys/byteorder.h>
#include <sys/ethernet.h>
#include <sys/mac_wifi.h>
#include <sys/net80211.h>
#include <sys/net80211_proto.h>
#include <inet/wifi_ioctl.h>
#define USBDRV_MAJOR_VER 2
#define USBDRV_MINOR_VER 0
#include "ural_reg.h"
#include "ural_var.h"
static void *ural_soft_state_p = NULL;
#define RAL_TXBUF_SIZE (IEEE80211_MAX_LEN)
#define RAL_RXBUF_SIZE (IEEE80211_MAX_LEN)
/* quickly determine if a given rate is CCK or OFDM */
#define URAL_N(a) (sizeof (a) / sizeof ((a)[0]))
/*
* Supported rates for 802.11a/b/g modes (in 500Kbps unit).
*/
static const struct ieee80211_rateset ural_rateset_11a =
{ 8, { 12, 18, 24, 36, 48, 72, 96, 108 } };
static const struct ieee80211_rateset ural_rateset_11b =
{ 4, { 2, 4, 11, 22 } };
static const struct ieee80211_rateset ural_rateset_11g =
{ 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
/*
* Default values for MAC registers; values taken from the reference driver.
*/
static const struct {
} ural_def_mac[] = {
{ RAL_TXRX_CSR5, 0x8c8d },
{ RAL_TXRX_CSR6, 0x8b8a },
{ RAL_TXRX_CSR7, 0x8687 },
{ RAL_TXRX_CSR8, 0x0085 },
{ RAL_MAC_CSR13, 0x1111 },
{ RAL_MAC_CSR14, 0x1e11 },
{ RAL_TXRX_CSR21, 0xe78f },
{ RAL_MAC_CSR9, 0xff1d },
{ RAL_MAC_CSR11, 0x0002 },
{ RAL_MAC_CSR22, 0x0053 },
{ RAL_MAC_CSR15, 0x0000 },
{ RAL_MAC_CSR8, 0x0780 },
{ RAL_TXRX_CSR19, 0x0000 },
{ RAL_TXRX_CSR18, 0x005a },
{ RAL_PHY_CSR2, 0x0000 },
{ RAL_TXRX_CSR0, 0x1ec0 },
{ RAL_PHY_CSR4, 0x000f }
};
/*
* Default values for BBP registers; values taken from the reference driver.
*/
static const struct {
} ural_def_bbp[] = {
{ 3, 0x02 },
{ 4, 0x19 },
{ 14, 0x1c },
{ 15, 0x30 },
{ 16, 0xac },
{ 17, 0x48 },
{ 18, 0x18 },
{ 19, 0xff },
{ 20, 0x1e },
{ 21, 0x08 },
{ 22, 0x08 },
{ 23, 0x08 },
{ 24, 0x80 },
{ 25, 0x50 },
{ 26, 0x08 },
{ 27, 0x23 },
{ 30, 0x10 },
{ 31, 0x2b },
{ 32, 0xb9 },
{ 34, 0x12 },
{ 35, 0x50 },
{ 39, 0xc4 },
{ 40, 0x02 },
{ 41, 0x60 },
{ 53, 0x10 },
{ 54, 0x18 },
{ 56, 0x08 },
{ 57, 0x10 },
{ 58, 0x08 },
{ 61, 0x60 },
{ 62, 0x10 },
{ 75, 0xff }
};
/*
* Default values for RF register R2 indexed by channel numbers.
*/
static const uint32_t ural_rf2522_r2[] = {
0x307f6, 0x307fb, 0x30800, 0x30805, 0x3080a, 0x3080f, 0x30814,
0x30819, 0x3081e, 0x30823, 0x30828, 0x3082d, 0x30832, 0x3083e
};
static const uint32_t ural_rf2523_r2[] = {
0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d,
0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346
};
static const uint32_t ural_rf2524_r2[] = {
0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d,
0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346
};
static const uint32_t ural_rf2525_r2[] = {
0x20327, 0x20328, 0x20329, 0x2032a, 0x2032b, 0x2032c, 0x2032d,
0x2032e, 0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20346
};
static const uint32_t ural_rf2525_hi_r2[] = {
0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20344, 0x20345,
0x20346, 0x20347, 0x20348, 0x20349, 0x2034a, 0x2034b, 0x2034e
};
static const uint32_t ural_rf2525e_r2[] = {
0x2044d, 0x2044e, 0x2044f, 0x20460, 0x20461, 0x20462, 0x20463,
0x20464, 0x20465, 0x20466, 0x20467, 0x20468, 0x20469, 0x2046b
};
static const uint32_t ural_rf2526_hi_r2[] = {
0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d, 0x0022d,
0x0022e, 0x0022e, 0x0022f, 0x0022d, 0x00240, 0x00240, 0x00241
};
static const uint32_t ural_rf2526_r2[] = {
0x00226, 0x00227, 0x00227, 0x00228, 0x00228, 0x00229, 0x00229,
0x0022a, 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d
};
/*
* For dual-band RF, RF registers R1 and R4 also depend on channel number;
* values taken from the reference driver.
*/
static const struct {
} ural_rf5222[] = {
{ 1, 0x08808, 0x0044d, 0x00282 },
{ 2, 0x08808, 0x0044e, 0x00282 },
{ 3, 0x08808, 0x0044f, 0x00282 },
{ 4, 0x08808, 0x00460, 0x00282 },
{ 5, 0x08808, 0x00461, 0x00282 },
{ 6, 0x08808, 0x00462, 0x00282 },
{ 7, 0x08808, 0x00463, 0x00282 },
{ 8, 0x08808, 0x00464, 0x00282 },
{ 9, 0x08808, 0x00465, 0x00282 },
{ 10, 0x08808, 0x00466, 0x00282 },
{ 11, 0x08808, 0x00467, 0x00282 },
{ 12, 0x08808, 0x00468, 0x00282 },
{ 13, 0x08808, 0x00469, 0x00282 },
{ 14, 0x08808, 0x0046b, 0x00286 },
{ 36, 0x08804, 0x06225, 0x00287 },
{ 40, 0x08804, 0x06226, 0x00287 },
{ 44, 0x08804, 0x06227, 0x00287 },
{ 48, 0x08804, 0x06228, 0x00287 },
{ 52, 0x08804, 0x06229, 0x00287 },
{ 56, 0x08804, 0x0622a, 0x00287 },
{ 60, 0x08804, 0x0622b, 0x00287 },
{ 64, 0x08804, 0x0622c, 0x00287 },
{ 100, 0x08804, 0x02200, 0x00283 },
{ 104, 0x08804, 0x02201, 0x00283 },
{ 108, 0x08804, 0x02202, 0x00283 },
{ 112, 0x08804, 0x02203, 0x00283 },
{ 116, 0x08804, 0x02204, 0x00283 },
{ 120, 0x08804, 0x02205, 0x00283 },
{ 124, 0x08804, 0x02206, 0x00283 },
{ 128, 0x08804, 0x02207, 0x00283 },
{ 132, 0x08804, 0x02208, 0x00283 },
{ 136, 0x08804, 0x02209, 0x00283 },
{ 140, 0x08804, 0x0220a, 0x00283 },
{ 149, 0x08808, 0x02429, 0x00281 },
{ 153, 0x08808, 0x0242b, 0x00281 },
{ 157, 0x08808, 0x0242d, 0x00281 },
{ 161, 0x08808, 0x0242f, 0x00281 }
};
/*
* device operations
*/
/*
* Module Loading Data & Entry Points
*/
static struct modldrv ural_modldrv = {
&mod_driverops, /* Type of module. This one is a driver */
"ural driver v1.3", /* short description */
&ural_dev_ops /* driver specific ops */
};
static struct modlinkage modlinkage = {
(void *)&ural_modldrv,
};
static int ural_m_start(void *);
static void ural_m_stop(void *);
static int ural_m_promisc(void *, boolean_t);
static int ural_m_unicst(void *, const uint8_t *);
static int ural_m_setprop(void *, const char *, mac_prop_id_t,
uint_t, const void *);
static int ural_m_getprop(void *, const char *, mac_prop_id_t,
static mac_callbacks_t ural_m_callbacks = {
NULL, /* mc_resources; */
NULL, /* mc_getcapab */
NULL,
NULL,
};
extern const char *usb_str_cr(int);
static int ural_rx_trigger(struct ural_softc *);
uint32_t ural_dbg_flags = 0;
#ifdef DEBUG
void
{
if (dbg_flags & ural_dbg_flags) {
}
}
#endif
static uint16_t
{
int err;
if (err != USB_SUCCESS) {
"ural_read(): could not read MAC register:"
" cr:%s(%d), cf:(%x)\n",
return (0);
}
if (mp)
}
static void
{
int err;
if (err != USB_SUCCESS) {
"ural_read_multi(): could not read MAC register:"
"cr:%s(%d), cf:(%x)\n",
return;
}
if (mp)
}
static void
{
int err;
if (err != USB_SUCCESS) {
"ural_write(): could not write MAC register:"
"cr:%s(%d), cf:(%x)\n",
}
}
/* ARGSUSED */
static void
{
"ural_txeof(): cr:%s(%d), flags:0x%x, tx_queued:%d",
sc->sc_tx_timer = 0;
if (sc->sc_need_sched) {
sc->sc_need_sched = 0;
}
}
/* ARGSUSED */
static void
{
struct ural_rx_desc *desc;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
char *rxbuf;
"ural_rxeof(): cr:%s(%d), flags:0x%x, rx_queued:%d",
goto fail;
}
"ural_rxeof(): xfer too short %d\n", len);
goto fail;
}
/* rx descriptor is located at the end */
/*
* This should not happen since we did not request to receive
* those frames when we filled RAL_TXRX_CSR2.
*/
goto fail;
}
goto fail;
}
/* Strip trailing 802.11 MAC FCS. */
"ural_rxeof(): allocate mblk failed.\n");
sc->sc_rx_nobuf++;
goto fail;
}
/* send the frame to the 802.11 layer */
/* node is no longer needed */
fail:
if (RAL_IS_RUNNING(sc))
(void) ural_rx_trigger(sc);
}
/*
* Return the expected ack rate for a frame transmitted at rate `rate'.
* this should depend on the destination node basic rate set.
*/
static int
{
switch (rate) {
/* CCK rates */
case 2:
return (2);
case 4:
case 11:
case 22:
/* OFDM rates */
case 12:
case 18:
return (12);
case 24:
case 36:
return (24);
case 48:
case 72:
case 96:
case 108:
return (48);
}
/* default to 1Mbps */
return (2);
}
/*
* Compute the duration (in us) needed to transmit `len' bytes at rate `rate'.
* The function automatically determines the operating mode depending on the
* given rate. `flags' indicates whether short preamble is in use or not.
*/
static uint16_t
{
if (RAL_RATE_IS_OFDM(rate)) {
/* IEEE Std 802.11a-1999, pp. 37 */
} else {
/* IEEE Std 802.11b-1999, pp. 28 */
else
}
return (txtime);
}
static uint8_t
ural_plcp_signal(int rate)
{
switch (rate) {
/* CCK rates (returned values are device-dependent) */
case 2: return (0x0);
case 4: return (0x1);
case 11: return (0x2);
case 22: return (0x3);
/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
case 12: return (0xb);
case 18: return (0xf);
case 24: return (0xa);
case 36: return (0xe);
case 48: return (0x9);
case 72: return (0xd);
case 96: return (0x8);
case 108: return (0xc);
/* unsupported rates (should not get there) */
default: return (0xff);
}
}
static void
{
int remainder;
/* setup PLCP fields */
len += IEEE80211_CRC_LEN;
if (RAL_RATE_IS_OFDM(rate)) {
} else {
if (rate == 22) {
}
}
}
#define RAL_TX_TIMEOUT 5
static int
{
struct ural_tx_desc *desc;
struct ieee80211_frame *wh;
struct ieee80211_key *k;
"no TX buffer available!\n");
if ((type & IEEE80211_FC0_TYPE_MASK) ==
}
sc->sc_tx_nobuf++;
goto fail;
}
if (m == NULL) {
err = DDI_FAILURE;
goto fail;
}
m->b_wptr += RAL_TX_DESC_SIZE;
}
err = DDI_FAILURE;
freemsg(m);
goto fail;
}
if ((type & IEEE80211_FC0_TYPE_MASK) ==
}
k = ieee80211_crypto_encap(ic, m);
if (k == NULL) {
freemsg(m);
err = DDI_FAILURE;
goto fail;
}
/* packet header may have moved, reset our local pointer */
}
if ((type & IEEE80211_FC0_TYPE_MASK) ==
IEEE80211_FC0_TYPE_DATA) { /* DATA */
else
if (rate <= 0) {
}
flags |= RAL_TX_ACK;
}
} else { /* MGMT */
flags |= RAL_TX_ACK;
+ RAL_SIFS;
/* tell hardware to add timestamp for probe responses */
}
}
/* align end on a 2-bytes boundary */
/*
* No space left in the last URB to store the extra 2 bytes, force
* sending of another URB.
*/
if ((xferlen % 64) == 0)
xferlen += 2;
(void) ural_tx_trigger(sc, m);
fail:
err == 0) {
}
return (err);
}
static mblk_t *
{
/*
* No data frames go out unless we're associated; this
* should not happen as the 802.11 layer does not enable
* the xmit queue until we enter the RUN state.
*/
return (NULL);
}
return (NULL);
}
}
return (mp);
}
static void
{
int err;
if (err != USB_SUCCESS) {
"ural_set_testmode(): could not set test mode:"
"cr:%s(%d), cf:%(x)\n",
}
}
static void
{
int err;
if (err != USB_SUCCESS) {
"ural_eeprom_read(): could not read EEPROM:"
"cr:%s(%d), cf:(%x)\n",
return;
}
if (mp)
}
static void
{
int ntries;
break;
}
if (ntries == 5) {
"ural_bbp_write(): could not write to BBP\n");
return;
}
}
static uint8_t
{
int ntries;
break;
}
if (ntries == 5) {
return (0);
}
}
static void
{
int ntries;
break;
}
if (ntries == 5) {
"ural_rf_write(): could not write to RF\n");
return;
}
/* remember last written value in sc */
}
/*
* Disable RF auto-tuning.
*/
static void
{
}
}
static void
{
return;
if (IEEE80211_IS_CHAN_2GHZ(c))
else
power = 31;
/* adjust txpower using ifconfig settings */
case RAL_RF_2522:
break;
case RAL_RF_2523:
break;
case RAL_RF_2524:
break;
case RAL_RF_2525:
break;
case RAL_RF_2525E:
break;
case RAL_RF_2526:
break;
/* dual-band RF */
case RAL_RF_5222:
if (i > URAL_N(ural_rf5222)) break;
}
break;
}
/* set Japan filter bit for channel 14 */
tmp &= ~RAL_JAPAN_FILTER;
if (chan == 14)
tmp |= RAL_JAPAN_FILTER;
/* clear CRC errs */
drv_usecwait(10000);
}
}
/*
* Refer to IEEE Std 802.11-1999 pp. 123 for more information on TSF
* synchronization.
*/
static void
{
/* first, disable TSF synchronization */
/* finally, enable TSF synchronization */
else
}
/*
* This function can be called by ieee80211_set_shortslottime(). Refer to
* IEEE Std 802.11-1999 pp. 85 to know how these values are computed.
*/
/* ARGSUSED */
static void
{
/* slottime = (onoff ? 9 : 20); */
/*
* These settings may sound a bit inconsistent but this is what the
* reference driver does.
*/
eifs = 364;
} else {
eifs = 64;
}
}
static void
{
tmp &= ~RAL_SHORT_PREAMBLE;
}
static void
{
/* update basic rate set */
/* 11b basic rates: 1, 2Mbps */
/* 11a basic rates: 6, 12, 24Mbps */
} else {
/* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */
}
}
static void
{
}
static void
{
}
static void
{
tmp &= ~RAL_DROP_NOT_TO_ME;
}
static const char *
ural_get_rf(int rev)
{
switch (rev) {
case RAL_RF_2522: return ("RT2522");
case RAL_RF_2523: return ("RT2523");
case RAL_RF_2524: return ("RT2524");
case RAL_RF_2525: return ("RT2525");
case RAL_RF_2525E: return ("RT2525e");
case RAL_RF_2526: return ("RT2526");
case RAL_RF_5222: return ("RT5222");
default: return ("unknown");
}
}
static void
{
/* read MAC address */
/* read default values for BBP registers */
/* read Tx power for all b/g channels */
}
static int
{
int i, ntries;
/* wait for BBP to be ready */
break;
drv_usecwait(1000);
}
if (ntries == 100) {
return (EIO);
}
/* initialize BBP registers to default values */
for (i = 0; i < URAL_N(ural_def_bbp); i++)
return (0);
}
static void
{
if (antenna == 1)
tx |= RAL_BBP_ANTA;
else if (antenna == 2)
tx |= RAL_BBP_ANTB;
else
tx |= RAL_BBP_DIVERSITY;
/* need to force I/Q flip for RF 2525e, 2526 and 5222 */
tx |= RAL_BBP_FLIPIQ;
/* update values in PHY_CSR5 and PHY_CSR6 */
}
static void
{
if (antenna == 1)
rx |= RAL_BBP_ANTA;
else if (antenna == 2)
rx |= RAL_BBP_ANTB;
else
rx |= RAL_BBP_DIVERSITY;
/* need to force no I/Q flip for RF 2525e and 2526 */
rx &= ~RAL_BBP_FLIPIQ;
}
/*
* This function is called periodically (every 200ms) during scanning to
* switch from one channel to another.
*/
static void
ural_next_scan(void *arg)
{
}
static int
{
enum ieee80211_state ostate;
struct ieee80211_node *ni;
int err;
if (sc->sc_scan_id != 0) {
sc->sc_scan_id = 0;
}
if (sc->sc_amrr_id != 0) {
sc->sc_amrr_id = 0;
}
switch (nstate) {
case IEEE80211_S_INIT:
if (ostate == IEEE80211_S_RUN) {
/* abort TSF synchronization */
/* force tx led to stop blinking */
}
break;
case IEEE80211_S_SCAN:
break;
case IEEE80211_S_AUTH:
break;
case IEEE80211_S_ASSOC:
break;
case IEEE80211_S_RUN:
}
/* make tx led blink on tx (controlled by ASIC) */
/* enable automatic rate adaptation in STA mode */
break;
}
RAL_UNLOCK(sc);
/*
* Finally, start any timers.
*/
if (nstate == IEEE80211_S_RUN)
return (err);
}
static void
{
}
}
}
static int
{
int err;
"ural_open_pipes(): %x failed to open tx pipe\n", err);
goto fail;
}
"ural_open_pipes(): %x failed to open rx pipe\n", err);
goto fail;
}
return (USB_SUCCESS);
fail:
USB_FLAGS_SLEEP, NULL, 0);
}
USB_FLAGS_SLEEP, NULL, 0);
}
return (USB_FAILURE);
}
static int
{
int err;
"ural_tx_trigger(): failed to allocate req");
return (-1);
}
req->bulk_completion_reason = 0;
req->bulk_cb_flags = 0;
!= USB_SUCCESS) {
"failed to do tx xfer, %d", err);
return (-1);
}
return (0);
}
static int
{
int err;
"ural_rx_trigger(): failed to allocate req");
return (-1);
}
req->bulk_timeout = 0;
req->bulk_completion_reason = 0;
req->bulk_cb_flags = 0;
if (err != USB_SUCCESS) {
"failed to do rx xfer, %d", err);
return (-1);
}
return (0);
}
static void
{
}
static int
{
int i;
for (i = 0; i < RAL_RX_LIST_COUNT; i++) {
if (ural_rx_trigger(sc) != 0) {
return (USB_FAILURE);
}
}
return (USB_SUCCESS);
}
static void
{
sc->sc_tx_timer = 0;
/* disable Rx */
/* reset ASIC and BBP (but won't reset MAC registers!) */
RAL_UNLOCK(sc);
}
static int
{
int i, ntries;
/* initialize MAC registers to default values */
for (i = 0; i < URAL_N(ural_def_mac); i++)
/* wait for BBP and RF to wake up (this can take a long time!) */
break;
drv_usecwait(1000);
}
if (ntries == 100) {
goto fail;
}
/* we're ready! */
/* set basic rate set (will be updated later) */
if (ural_bbp_init(sc) != 0)
goto fail;
/* set default BSS channel */
/* clear statistic registers (STA_CSR0 to STA_CSR10) */
"could not open pipes.\n");
goto fail;
}
goto fail;
/* kick Rx */
tmp |= RAL_DROP_TODS;
}
return (DDI_SUCCESS);
fail:
return (EIO);
}
static int
{
struct ural_softc *sc;
struct ieee80211com *ic;
/*
* We can't call ural_stop() here, since the hardware is removed,
* we can't access the register anymore.
*/
sc->sc_tx_timer = 0;
RAL_UNLOCK(sc);
return (DDI_SUCCESS);
}
static int
{
struct ural_softc *sc;
int err;
return (err);
}
#define URAL_AMRR_MIN_SUCCESS_THRESHOLD 1
#define URAL_AMRR_MAX_SUCCESS_THRESHOLD 10
/*
* Naive implementation of the Adaptive Multi Rate Retry algorithm:
* "IEEE 802.11 Rate Adaptation: A Practical Approach"
* Mathieu Lacage, Hossein Manshaei, Thierry Turletti
* INRIA Sophia - Projet Planete
*
* This algorithm is particularly well suited for ural since it does not
* require per-frame retry statistics. Note however that since h/w does
* not provide per-frame stats, we can't do per-node rate adaptation and
* thus automatic rate adaptation is only enabled in STA operating mode.
*/
#define is_success(amrr) \
#define is_failure(amrr) \
#define is_min_rate(ni) \
#define is_max_rate(ni) \
#define increase_rate(ni) \
#define decrease_rate(ni) \
} while (/* CONSTCOND */0)
static void
{
int need_change = 0;
!is_max_rate(ni)) {
need_change = 1;
} else {
}
} else if (is_failure(amrr)) {
if (!is_min_rate(ni)) {
if (amrr->success_threshold >
} else {
}
need_change = 1;
}
}
}
static void
ural_amrr_timeout(void *arg)
{
/* count TX retry-fail as Tx errors */
}
static void
{
int i;
/* clear statistic registers (STA_CSR0 to STA_CSR10) */
/* set rate to some reasonable initial value */
i--) {
}
}
void
ural_watchdog(void *arg)
{
int ntimer = 0;
ic->ic_watchdog_timer = 0;
if (!RAL_IS_RUNNING(sc)) {
RAL_UNLOCK(sc);
return;
}
if (sc->sc_tx_timer > 0) {
if (--sc->sc_tx_timer == 0) {
RAL_UNLOCK(sc);
return;
}
}
ntimer = 1;
RAL_UNLOCK(sc);
if (ntimer)
}
static int
ural_m_start(void *arg)
{
int err;
/*
* initialize RT2500USB hardware
*/
if (err != DDI_SUCCESS) {
goto fail;
}
return (err);
fail:
return (err);
}
static void
ural_m_stop(void *arg)
{
}
static int
{
return (0);
}
/*ARGSUSED*/
static int
{
return (0);
}
static int
{
if (on) {
} else {
}
return (0);
}
/*
*/
static int
{
int err;
if (RAL_IS_RUNNING(sc)) {
RAL_UNLOCK(sc);
}
err = 0;
}
RAL_UNLOCK(sc);
return (err);
}
static int
{
int err;
return (err);
}
static void
{
int err;
if (RAL_IS_RUNNING(sc)) {
RAL_UNLOCK(sc);
}
}
RAL_UNLOCK(sc);
}
static int
{
switch (stat) {
case MAC_STAT_IFSPEED:
break;
case MAC_STAT_NOXMTBUF:
break;
case MAC_STAT_NORCVBUF:
break;
case MAC_STAT_IERRORS:
break;
case MAC_STAT_RBYTES:
break;
case MAC_STAT_IPACKETS:
break;
case MAC_STAT_OBYTES:
break;
case MAC_STAT_OPACKETS:
break;
case MAC_STAT_OERRORS:
case WIFI_STAT_TX_FAILED:
break;
case WIFI_STAT_TX_RETRANS:
break;
case WIFI_STAT_FCS_ERRORS:
case WIFI_STAT_WEP_ERRORS:
case WIFI_STAT_TX_FRAGS:
case WIFI_STAT_MCAST_TX:
case WIFI_STAT_RTS_SUCCESS:
case WIFI_STAT_RTS_FAILURE:
case WIFI_STAT_ACK_FAILURE:
case WIFI_STAT_RX_FRAGS:
case WIFI_STAT_MCAST_RX:
case WIFI_STAT_RX_DUPS:
RAL_UNLOCK(sc);
default:
RAL_UNLOCK(sc);
return (ENOTSUP);
}
RAL_UNLOCK(sc);
return (0);
}
static int
{
struct ural_softc *sc;
struct ieee80211com *ic;
int err, i;
int instance;
char strbuf[32];
wifi_data_t wd = { 0 };
if (cmd != DDI_ATTACH)
return (DDI_FAILURE);
"unable to alloc soft_state_p\n");
return (DDI_FAILURE);
}
"ural_attach(): usb_client_attach failed\n");
goto fail1;
}
USB_PARSE_LVL_ALL, 0) != USB_SUCCESS) {
goto fail2;
}
/* retrieve RT2570 rev. no */
/* retrieve MAC address and various other things from EEPROM */
/* set device capabilities */
IEEE80211_C_TXPMGT | /* tx power management */
IEEE80211_C_SHPREAMBLE | /* short preamble supported */
IEEE80211_C_SHSLOT; /* short slot time supported */
#define IEEE80211_CHAN_A \
/* set supported .11a rates */
/* set supported .11a channels */
for (i = 36; i <= 64; i += 4) {
}
for (i = 100; i <= 140; i += 4) {
}
for (i = 149; i <= 161; i += 4) {
}
}
/* set supported .11b and .11g rates */
/* set supported .11b and .11g channels (1 through 14) */
for (i = 1; i <= 14; i++) {
}
/* register WPA door */
/* override state transition machine */
ic->ic_def_txkey = 0;
/*
* Provide initial settings for the WiFi plugin; whenever this
* information changes, we need to call mac_plugindata_update()
*/
"MAC version mismatch\n");
goto fail3;
}
if (err != 0) {
"mac_register() err %x\n", err);
goto fail3;
}
ural_online) != USB_SUCCESS) {
"ural: ural_attach() failed to register events");
goto fail4;
}
/*
* Create minor node of type DDI_NT_NET_WIFI
*/
"ural", instance);
if (err != DDI_SUCCESS)
/*
* Notify link is down now
*/
return (DDI_SUCCESS);
return (DDI_FAILURE);
}
static int
{
struct ural_softc *sc;
if (cmd != DDI_DETACH)
return (DDI_FAILURE);
return (DDI_FAILURE);
/*
* Unregister from the MAC layer subsystem
*/
/*
* detach ieee80211 layer
*/
/* pipes will be close in ural_stop() */
return (DDI_SUCCESS);
}
int
{
}
int
_init(void)
{
int status;
sizeof (struct ural_softc), 1);
if (status != 0)
return (status);
if (status != 0) {
}
return (status);
}
int
_fini(void)
{
int status;
if (status == 0) {
}
return (status);
}