/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
*/
#include <sys/mac_provider.h>
#include <sys/mac_wifi.h>
#include <sys/net80211.h>
#include <sys/byteorder.h>
#define USBDRV_MINOR_VER 0
#include "rum_reg.h"
#include "rum_var.h"
#include "rt2573_ucode.h"
/* quickly determine if a given rate is CCK or OFDM */
#define RUM_N(a) (sizeof (a) / sizeof ((a)[0]))
/*
* Supported rates for 802.11a/b/g modes (in 500Kbps unit).
*/
{ 8, { 12, 18, 24, 36, 48, 72, 96, 108 } };
{ 4, { 2, 4, 11, 22 } };
{ 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
static const struct {
} rum_def_mac[] = {
{ RT2573_TXRX_CSR0, 0x025fb032 },
{ RT2573_TXRX_CSR1, 0x9eaa9eaf },
{ RT2573_TXRX_CSR2, 0x8a8b8c8d },
{ RT2573_TXRX_CSR3, 0x00858687 },
{ RT2573_TXRX_CSR7, 0x2e31353b },
{ RT2573_TXRX_CSR8, 0x2a2a2a2c },
{ RT2573_TXRX_CSR15, 0x0000000f },
{ RT2573_MAC_CSR6, 0x00000fff },
{ RT2573_MAC_CSR8, 0x016c030a },
{ RT2573_MAC_CSR10, 0x00000718 },
{ RT2573_MAC_CSR12, 0x00000004 },
{ RT2573_MAC_CSR13, 0x00007f00 },
{ RT2573_SEC_CSR0, 0x00000000 },
{ RT2573_SEC_CSR1, 0x00000000 },
{ RT2573_SEC_CSR5, 0x00000000 },
{ RT2573_PHY_CSR1, 0x000023b0 },
{ RT2573_PHY_CSR5, 0x00040a06 },
{ RT2573_PHY_CSR6, 0x00080606 },
{ RT2573_PHY_CSR7, 0x00000408 },
{ RT2573_AIFSN_CSR, 0x00002273 },
{ RT2573_CWMIN_CSR, 0x00002344 },
{ RT2573_CWMAX_CSR, 0x000034aa }
};
static const struct {
} rum_def_bbp[] = {
{ 3, 0x80 },
{ 15, 0x30 },
{ 17, 0x20 },
{ 21, 0xc8 },
{ 22, 0x38 },
{ 23, 0x06 },
{ 24, 0xfe },
{ 25, 0x0a },
{ 26, 0x0d },
{ 32, 0x0b },
{ 34, 0x12 },
{ 37, 0x07 },
{ 39, 0xf8 },
{ 41, 0x60 },
{ 53, 0x10 },
{ 54, 0x18 },
{ 60, 0x10 },
{ 61, 0x04 },
{ 62, 0x04 },
{ 75, 0xfe },
{ 86, 0xfe },
{ 88, 0xfe },
{ 90, 0x0f },
{ 99, 0x00 },
{ 102, 0x16 },
{ 107, 0x04 }
};
static const struct rfprog {
} rum_rf5226[] = {
{ 1, 0x00b03, 0x001e1, 0x1a014, 0x30282 },
{ 2, 0x00b03, 0x001e1, 0x1a014, 0x30287 },
{ 3, 0x00b03, 0x001e2, 0x1a014, 0x30282 },
{ 4, 0x00b03, 0x001e2, 0x1a014, 0x30287 },
{ 5, 0x00b03, 0x001e3, 0x1a014, 0x30282 },
{ 6, 0x00b03, 0x001e3, 0x1a014, 0x30287 },
{ 7, 0x00b03, 0x001e4, 0x1a014, 0x30282 },
{ 8, 0x00b03, 0x001e4, 0x1a014, 0x30287 },
{ 9, 0x00b03, 0x001e5, 0x1a014, 0x30282 },
{ 10, 0x00b03, 0x001e5, 0x1a014, 0x30287 },
{ 11, 0x00b03, 0x001e6, 0x1a014, 0x30282 },
{ 12, 0x00b03, 0x001e6, 0x1a014, 0x30287 },
{ 13, 0x00b03, 0x001e7, 0x1a014, 0x30282 },
{ 14, 0x00b03, 0x001e8, 0x1a014, 0x30284 },
{ 34, 0x00b03, 0x20266, 0x36014, 0x30282 },
{ 38, 0x00b03, 0x20267, 0x36014, 0x30284 },
{ 42, 0x00b03, 0x20268, 0x36014, 0x30286 },
{ 46, 0x00b03, 0x20269, 0x36014, 0x30288 },
{ 36, 0x00b03, 0x00266, 0x26014, 0x30288 },
{ 40, 0x00b03, 0x00268, 0x26014, 0x30280 },
{ 44, 0x00b03, 0x00269, 0x26014, 0x30282 },
{ 48, 0x00b03, 0x0026a, 0x26014, 0x30284 },
{ 52, 0x00b03, 0x0026b, 0x26014, 0x30286 },
{ 56, 0x00b03, 0x0026c, 0x26014, 0x30288 },
{ 60, 0x00b03, 0x0026e, 0x26014, 0x30280 },
{ 64, 0x00b03, 0x0026f, 0x26014, 0x30282 },
{ 100, 0x00b03, 0x0028a, 0x2e014, 0x30280 },
{ 104, 0x00b03, 0x0028b, 0x2e014, 0x30282 },
{ 108, 0x00b03, 0x0028c, 0x2e014, 0x30284 },
{ 112, 0x00b03, 0x0028d, 0x2e014, 0x30286 },
{ 116, 0x00b03, 0x0028e, 0x2e014, 0x30288 },
{ 120, 0x00b03, 0x002a0, 0x2e014, 0x30280 },
{ 124, 0x00b03, 0x002a1, 0x2e014, 0x30282 },
{ 128, 0x00b03, 0x002a2, 0x2e014, 0x30284 },
{ 132, 0x00b03, 0x002a3, 0x2e014, 0x30286 },
{ 136, 0x00b03, 0x002a4, 0x2e014, 0x30288 },
{ 140, 0x00b03, 0x002a6, 0x2e014, 0x30280 },
{ 149, 0x00b03, 0x002a8, 0x2e014, 0x30287 },
{ 153, 0x00b03, 0x002a9, 0x2e014, 0x30289 },
{ 157, 0x00b03, 0x002ab, 0x2e014, 0x30281 },
{ 161, 0x00b03, 0x002ac, 0x2e014, 0x30283 },
{ 165, 0x00b03, 0x002ad, 0x2e014, 0x30285 }
}, rum_rf5225[] = {
{ 1, 0x00b33, 0x011e1, 0x1a014, 0x30282 },
{ 2, 0x00b33, 0x011e1, 0x1a014, 0x30287 },
{ 3, 0x00b33, 0x011e2, 0x1a014, 0x30282 },
{ 4, 0x00b33, 0x011e2, 0x1a014, 0x30287 },
{ 5, 0x00b33, 0x011e3, 0x1a014, 0x30282 },
{ 6, 0x00b33, 0x011e3, 0x1a014, 0x30287 },
{ 7, 0x00b33, 0x011e4, 0x1a014, 0x30282 },
{ 8, 0x00b33, 0x011e4, 0x1a014, 0x30287 },
{ 9, 0x00b33, 0x011e5, 0x1a014, 0x30282 },
{ 10, 0x00b33, 0x011e5, 0x1a014, 0x30287 },
{ 11, 0x00b33, 0x011e6, 0x1a014, 0x30282 },
{ 12, 0x00b33, 0x011e6, 0x1a014, 0x30287 },
{ 13, 0x00b33, 0x011e7, 0x1a014, 0x30282 },
{ 14, 0x00b33, 0x011e8, 0x1a014, 0x30284 },
{ 34, 0x00b33, 0x01266, 0x26014, 0x30282 },
{ 38, 0x00b33, 0x01267, 0x26014, 0x30284 },
{ 42, 0x00b33, 0x01268, 0x26014, 0x30286 },
{ 46, 0x00b33, 0x01269, 0x26014, 0x30288 },
{ 36, 0x00b33, 0x01266, 0x26014, 0x30288 },
{ 40, 0x00b33, 0x01268, 0x26014, 0x30280 },
{ 44, 0x00b33, 0x01269, 0x26014, 0x30282 },
{ 48, 0x00b33, 0x0126a, 0x26014, 0x30284 },
{ 52, 0x00b33, 0x0126b, 0x26014, 0x30286 },
{ 56, 0x00b33, 0x0126c, 0x26014, 0x30288 },
{ 60, 0x00b33, 0x0126e, 0x26014, 0x30280 },
{ 64, 0x00b33, 0x0126f, 0x26014, 0x30282 },
{ 100, 0x00b33, 0x0128a, 0x2e014, 0x30280 },
{ 104, 0x00b33, 0x0128b, 0x2e014, 0x30282 },
{ 108, 0x00b33, 0x0128c, 0x2e014, 0x30284 },
{ 112, 0x00b33, 0x0128d, 0x2e014, 0x30286 },
{ 116, 0x00b33, 0x0128e, 0x2e014, 0x30288 },
{ 120, 0x00b33, 0x012a0, 0x2e014, 0x30280 },
{ 124, 0x00b33, 0x012a1, 0x2e014, 0x30282 },
{ 128, 0x00b33, 0x012a2, 0x2e014, 0x30284 },
{ 132, 0x00b33, 0x012a3, 0x2e014, 0x30286 },
{ 136, 0x00b33, 0x012a4, 0x2e014, 0x30288 },
{ 140, 0x00b33, 0x012a6, 0x2e014, 0x30280 },
{ 149, 0x00b33, 0x012a8, 0x2e014, 0x30287 },
{ 153, 0x00b33, 0x012a9, 0x2e014, 0x30289 },
{ 157, 0x00b33, 0x012ab, 0x2e014, 0x30281 },
{ 161, 0x00b33, 0x012ac, 0x2e014, 0x30283 },
{ 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 }
};
/*
* device operations
*/
/*
* Module Loading Data & Entry Points
*/
&mod_driverops, /* Type of module. This one is a driver */
"rum driver v1.2", /* short description */
&rum_dev_ops /* driver specific ops */
};
(void *)&rum_modldrv,
};
static int rum_m_start(void *);
static void rum_m_stop(void *);
static int rum_m_promisc(void *, boolean_t);
static int rum_m_unicst(void *, const uint8_t *);
static int rum_m_setprop(void *, const char *, mac_prop_id_t,
uint_t, const void *);
static int rum_m_getprop(void *, const char *, mac_prop_id_t,
uint_t, void *);
static void rum_m_propinfo(void *, const char *, mac_prop_id_t,
NULL,
NULL, /* mc_getcapab */
NULL,
NULL,
};
static int rum_rx_trigger(struct rum_softc *);
void
{
if (dbg_flags & rum_dbg_flags) {
}
}
static void
{
int err;
if (err != USB_SUCCESS) {
"rum_read_multi(): could not read MAC register:"
"cr:%s(%d), cf:(%x)\n",
return;
}
}
static uint32_t
{
}
static void
{
int err;
return;
}
if (err != USB_SUCCESS) {
"rum_write_multi(): could not write MAC register:"
"cr:%s(%d), cf:(%x)\n",
}
}
static void
{
}
static int
{
int err;
int size;
size = sizeof (rt2573_ucode);
/* copy firmware image into NIC */
/* rum_write(sc, reg, *(uint32_t *)(ucode)); */
}
if (err != USB_SUCCESS) {
"rum_load_microcode(): could not run firmware: "
"cr:%s(%d), cf:(%x)\n",
}
"rum_load_microcode(%d): done\n", sizeof (rt2573_ucode));
return (err);
}
static void
{
int err;
if (err != USB_SUCCESS) {
"rum_eeprom_read(): could not read EEPROM:"
"cr:%s(%d), cf:(%x)\n",
return;
}
}
/* ARGSUSED */
static void
{
"rum_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
{
char *rxbuf;
"rum_rxeof(): cr:%s(%d), flags:0x%x, rx_queued:%d",
goto fail;
}
"rum_rxeof(): xfer too short %d\n", len);
goto fail;
}
/* rx descriptor is located at the head, different from RT2500USB */
/*
* This should not happen since we did not request to receive
* those frames when we filled RT2573_TXRX_CSR0.
*/
goto fail;
}
goto fail;
}
"rum_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) rum_rx_trigger(sc);
}
/*
* Return the expected ack rate for a frame transmitted at rate `rate'.
*/
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 (RUM_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
{
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 (RUM_RATE_IS_OFDM(rate)) {
} else {
if (rate == 22) {
}
}
}
static int
{
struct ieee80211_key *k;
/* discard packets while suspending or not inited */
if (!RAL_IS_RUNNING(sc)) {
return (ENXIO);
}
"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 += RT2573_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) {
err = DDI_FAILURE;
freemsg(m);
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) {
}
}
} else { /* MGMT */
/* tell hardware to add timestamp for probe responses */
}
}
/* align end on a 4-bytes boundary */
/*
* No space left in the last URB to store the extra 4 bytes, force
* sending of another URB.
*/
if ((xferlen % 64) == 0)
xferlen += 4;
if (rv == 0) {
}
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 ntries;
break;
}
if (ntries == 5) {
"rum_bbp_write(): could not write to BBP\n");
return;
}
}
static uint8_t
{
int ntries;
break;
}
if (ntries == 5) {
return (0);
}
if (!(val & RT2573_BBP_BUSY))
return (val & 0xff);
drv_usecwait(1);
}
return (0);
}
static void
{
int ntries;
break;
}
if (ntries == 5) {
"rum_rf_write(): could not write to RF\n");
return;
}
(reg & 3);
/* remember last written value in sc */
}
static void
{
/* make sure Rx is disabled before switching antenna */
}
/*
* Enable multi-rate retries for frames sent at OFDM rates.
* In 802.11b/g mode, allow fallback to CCK rates.
*/
static void
{
}
static void
{
tmp &= ~RT2573_SHORT_PREAMBLE;
}
static void
{
/* update basic rate set */
/* 11b basic rates: 1, 2Mbps */
/* 11a basic rates: 6, 12, 24Mbps */
} else {
/* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
}
}
/*
* driver.
*/
static void
{
/* update all BBP registers that depend on the band */
if (IEEE80211_IS_CHAN_5GHZ(c)) {
}
}
}
if (IEEE80211_IS_CHAN_2GHZ(c))
tmp |= RT2573_PA_PE_2GHZ;
else
tmp |= RT2573_PA_PE_5GHZ;
/* 802.11a uses a 16 microseconds short interframe space */
}
static void
{
return;
/* select the appropriate RF settings based on what EEPROM says */
/* find the settings for this channel (we know it exists) */
}
if (power < 0) {
power = 0;
} else if (power > 31) {
power = 31;
}
/*
* If we are switching from the 2GHz band to the 5GHz band or
* vice-versa, BBP registers need to be reprogrammed.
*/
rum_select_band(sc, c);
}
ic->ic_curchan = c;
drv_usecwait(10);
/* enable smart mode for MIMO-capable RFs */
bbp3 &= ~RT2573_SMART_MODE;
if (bbp94 != RT2573_BBPR94_DEFAULT)
}
/*
* Enable TSF synchronization and tell h/w to start sending beacons for IBSS
* and HostAP operating modes.
*/
static void
{
/*
* Change default 16ms TBTT adjustment to 8ms.
* Must be done before enabling beacon generation.
*/
}
/* set beacon interval (in 1/16ms unit) */
else
}
/* ARGSUSED */
static void
{
}
static void
{
}
static void
{
}
static void
{
tmp &= ~RT2573_DROP_NOT_TO_ME;
}
static const char *
{
switch (rev) {
case RT2573_RF_2527: return ("RT2527 (MIMO XR)");
case RT2573_RF_2528: return ("RT2528");
case RT2573_RF_5225: return ("RT5225 (MIMO XR)");
case RT2573_RF_5226: return ("RT5226");
default: return ("unknown");
}
}
static void
{
/* read MAC address */
/* read Tx power for all a/b/g channels */
/* default Tx power for 802.11a channels */
/* read default values for BBP registers */
}
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 < RUM_N(rum_def_bbp); i++)
/* write vendor-specific BBP values (from EEPROM) */
for (i = 0; i < 16; i++) {
continue;
}
return (0);
}
/*
* This function is called periodically (every 200ms) during scanning to
* switch from one channel to another.
*/
static void
{
}
static int
{
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 */
}
break;
case IEEE80211_S_SCAN:
break;
case IEEE80211_S_AUTH:
break;
case IEEE80211_S_ASSOC:
break;
case IEEE80211_S_RUN:
}
/* 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;
"rum_open_pipes(): %x failed to open tx pipe\n", err);
goto fail;
}
"rum_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;
"rum_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;
"rum_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 (rum_rx_trigger(sc) != 0) {
return (USB_FAILURE);
}
}
return (USB_SUCCESS);
}
static void
{
sc->sc_tx_timer = 0;
/* disable Rx */
/* reset ASIC */
RAL_UNLOCK(sc);
}
static int
{
int i, ntries;
/* initialize MAC registers to default values */
for (i = 0; i < RUM_N(rum_def_mac); i++)
/* set host ready */
break;
drv_usecwait(1000);
}
if (ntries == 1000) {
goto fail;
}
if (rum_bbp_init(sc) != 0)
goto fail;
/* select default channel */
/* clear STA registers */
/* initialize ASIC */
"could not open pipes.\n");
goto fail;
}
goto fail;
/* update Rx filter */
tmp |= RT2573_DROP_TODS;
}
return (DDI_SUCCESS);
fail:
return (DDI_FAILURE);
}
static int
{
/*
* We can't call rum_stop() here, since the hardware is removed,
* we can't access the register anymore.
*/
return (DDI_SUCCESS);
sc->sc_tx_timer = 0;
RAL_UNLOCK(sc);
return (DDI_SUCCESS);
}
static int
{
int err;
/* check device changes after disconnect */
return (DDI_FAILURE);
}
if (err != USB_SUCCESS) {
goto fail;
}
fail:
return (err);
}
static void
{
int err;
/* check device changes after suspend */
return;
}
if (err != USB_SUCCESS) {
return;
}
}
/*
* 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 rum 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.
*/
} 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
{
/* count TX retry-fail as Tx errors */
}
static void
{
int i;
/* clear statistic registers (STA_CSR0 to STA_CSR5) */
/* set rate to some reasonable initial value */
i--) {
}
}
void
{
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
{
int err;
/*
* initialize RT2501USB hardware
*/
if (err != DDI_SUCCESS) {
goto fail;
}
return (err);
fail:
return (err);
}
static void
{
}
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
{
}
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
{
int instance;
switch (cmd) {
case DDI_ATTACH:
break;
case DDI_RESUME:
rum_resume(sc);
return (DDI_SUCCESS);
default:
return (DDI_FAILURE);
}
"unable to alloc soft_state_p\n");
return (DDI_FAILURE);
}
"rum_attach(): usb_client_attach failed\n");
goto fail1;
}
USB_PARSE_LVL_ALL, 0) != USB_SUCCESS) {
goto fail2;
}
/* retrieve RT2573 rev. no */
break;
drv_usecwait(1000);
}
if (ntries == 1000) {
"rum_attach(): timeout waiting for chip to settle\n");
goto fail3;
}
/* retrieve MAC address and various other things from EEPROM */
if (err != USB_SUCCESS) {
goto fail3;
}
/* 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 = 34; i <= 46; i += 4) {
}
for (i = 36; i <= 64; i += 4) {
}
for (i = 100; i <= 140; i += 4) {
}
for (i = 149; i <= 165; 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;
}
rum_reconnect) != USB_SUCCESS) {
"rum_attach() failed to register events");
goto fail4;
}
/*
* Create minor node of type DDI_NT_NET_WIFI
*/
"rum", instance);
if (err != DDI_SUCCESS)
/*
* Notify link is down now
*/
return (DDI_SUCCESS);
return (DDI_FAILURE);
}
static int
{
switch (cmd) {
case DDI_DETACH:
break;
case DDI_SUSPEND:
if (RAL_IS_RUNNING(sc))
return (DDI_SUCCESS);
default:
return (DDI_FAILURE);
}
/*
* Unregister from the MAC layer subsystem
*/
return (DDI_FAILURE);
/*
* detach ieee80211 layer
*/
/* pipes will be closed in rum_stop() */
return (DDI_SUCCESS);
}
int
{
}
int
_init(void)
{
int status;
sizeof (struct rum_softc), 1);
if (status != 0)
return (status);
if (status != 0) {
}
return (status);
}
int
_fini(void)
{
int status;
if (status == 0) {
}
return (status);
}