summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/usbdevs3
-rw-r--r--sys/dev/usb/wlan/if_rsu.c11
-rw-r--r--sys/dev/usb/wlan/if_rum.c13
-rw-r--r--sys/dev/usb/wlan/if_run.c1046
-rw-r--r--sys/dev/usb/wlan/if_runreg.h587
-rw-r--r--sys/dev/usb/wlan/if_runvar.h12
-rw-r--r--sys/dev/usb/wlan/if_uath.c9
-rw-r--r--sys/dev/usb/wlan/if_upgt.c9
-rw-r--r--sys/dev/usb/wlan/if_ural.c13
-rw-r--r--sys/dev/usb/wlan/if_urtw.c11
-rw-r--r--sys/dev/usb/wlan/if_urtwn.c9
-rw-r--r--sys/dev/usb/wlan/if_zyd.c9
12 files changed, 1428 insertions, 304 deletions
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 5f94734..fe74e93 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -1549,6 +1549,8 @@ product DLINK DWLG122 0x3c00 DWL-G122 b1 Wireless Adapter
product DLINK DUBE100B1 0x3c05 DUB-E100 rev B1
product DLINK RT2870 0x3c09 RT2870
product DLINK RT3072 0x3c0a RT3072
+product DLINK DWA140B3 0x3c15 DWA-140 rev B3
+product DLINK DWA160B2 0x3c1a DWA-160 rev B2
product DLINK DWA127 0x3c1b DWA-127 Wireless Adapter
product DLINK DSB650C 0x4000 10Mbps Ethernet
product DLINK DSB650TX1 0x4001 10/100 Ethernet
@@ -3572,6 +3574,7 @@ product RALINK RT3072 0x3072 RT3072
product RALINK RT3370 0x3370 RT3370
product RALINK RT3572 0x3572 RT3572
product RALINK RT5370 0x5370 RT5370
+product RALINK RT5572 0x5572 RT5572
product RALINK RT8070 0x8070 RT8070
product RALINK RT2570_3 0x9020 RT2500USB Wireless Adapter
product RALINK RT2573_2 0x9021 RT2501USB Wireless Adapter
diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c
index 30cdbe9..ab1cfa0 100644
--- a/sys/dev/usb/wlan/if_rsu.c
+++ b/sys/dev/usb/wlan/if_rsu.c
@@ -480,8 +480,13 @@ rsu_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (uvp == NULL)
return (NULL);
vap = &uvp->vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags, bssid, mac);
+
+ if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
+ flags, bssid, mac) != 0) {
+ /* out of memory */
+ free(uvp, M_80211_VAP);
+ return (NULL);
+ }
/* override state transition machine */
uvp->newstate = vap->iv_newstate;
@@ -1153,7 +1158,7 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len)
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
IEEE80211_FC0_SUBTYPE_BEACON;
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
- *(uint16_t *)wh->i_dur = 0;
+ USETW(wh->i_dur, 0);
IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
IEEE80211_ADDR_COPY(wh->i_addr2, bss->macaddr);
IEEE80211_ADDR_COPY(wh->i_addr3, bss->macaddr);
diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c
index fa4e9f1..af11016 100644
--- a/sys/dev/usb/wlan/if_rum.c
+++ b/sys/dev/usb/wlan/if_rum.c
@@ -604,8 +604,13 @@ rum_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
return NULL;
vap = &rvp->vap;
/* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
+
+ if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
+ flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ /* out of memory */
+ free(rvp, M_80211_VAP);
+ return (NULL);
+ }
/* override state transition machine */
rvp->newstate = vap->iv_newstate;
@@ -1131,7 +1136,7 @@ rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
dur = ieee80211_ack_duration(ic->ic_rt, tp->mgmtrate,
ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- *(uint16_t *)wh->i_dur = htole16(dur);
+ USETW(wh->i_dur, dur);
/* tell hardware to add timestamp for probe responses */
if ((wh->i_fc[0] &
@@ -1275,7 +1280,7 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
dur = ieee80211_ack_duration(ic->ic_rt, rate,
ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- *(uint16_t *)wh->i_dur = htole16(dur);
+ USETW(wh->i_dur, dur);
}
rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, rate);
diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
index 985c4a7..37e73a7 100644
--- a/sys/dev/usb/wlan/if_run.c
+++ b/sys/dev/usb/wlan/if_run.c
@@ -2,6 +2,7 @@
* Copyright (c) 2008,2010 Damien Bergamini <damien.bergamini@free.fr>
* ported to FreeBSD by Akinori Furukoshi <moonlightakkiy@yahoo.ca>
* USB Consulting, Hans Petter Selasky <hselasky@freebsd.org>
+ * Copyright (c) 2013 Kevin Lo
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -20,7 +21,7 @@
__FBSDID("$FreeBSD$");
/*-
- * Ralink Technology RT2700U/RT2800U/RT3000U chipset driver.
+ * Ralink Technology RT2700U/RT2800U/RT3000U/RT3900E chipset driver.
* http://www.ralinktech.com/
*/
@@ -74,8 +75,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/wlan/if_runreg.h>
#include <dev/usb/wlan/if_runvar.h>
-#define N(_a) ((int)(sizeof((_a)) / sizeof((_a)[0])))
-
#ifdef USB_DEBUG
#define RUN_DEBUG
#endif
@@ -173,6 +172,8 @@ static const STRUCT_USB_HOST_ID run_devs[] = {
RUN_DEV(DLINK, RT2870),
RUN_DEV(DLINK, RT3072),
RUN_DEV(DLINK, DWA127),
+ RUN_DEV(DLINK, DWA140B3),
+ RUN_DEV(DLINK, DWA160B2),
RUN_DEV(DLINK2, DWA130),
RUN_DEV(DLINK2, RT2870_1),
RUN_DEV(DLINK2, RT2870_2),
@@ -256,6 +257,8 @@ static const STRUCT_USB_HOST_ID run_devs[] = {
RUN_DEV(RALINK, RT3072),
RUN_DEV(RALINK, RT3370),
RUN_DEV(RALINK, RT3572),
+ RUN_DEV(RALINK, RT5370),
+ RUN_DEV(RALINK, RT5572),
RUN_DEV(RALINK, RT8070),
RUN_DEV(SAMSUNG, WIS09ABGN),
RUN_DEV(SAMSUNG2, RT2870_1),
@@ -319,7 +322,7 @@ static usb_callback_t run_bulk_tx_callback4;
static usb_callback_t run_bulk_tx_callback5;
static void run_bulk_tx_callbackN(struct usb_xfer *xfer,
- usb_error_t error, unsigned int index);
+ usb_error_t error, u_int index);
static struct ieee80211vap *run_vap_create(struct ieee80211com *,
const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
const uint8_t [IEEE80211_ADDR_LEN],
@@ -343,13 +346,13 @@ static int run_write_region_1(struct run_softc *, uint16_t,
static int run_set_region_4(struct run_softc *, uint16_t, uint32_t, int);
static int run_efuse_read_2(struct run_softc *, uint16_t, uint16_t *);
static int run_eeprom_read_2(struct run_softc *, uint16_t, uint16_t *);
-static int run_rt2870_rf_write(struct run_softc *, uint8_t, uint32_t);
+static int run_rt2870_rf_write(struct run_softc *, uint32_t);
static int run_rt3070_rf_read(struct run_softc *, uint8_t, uint8_t *);
static int run_rt3070_rf_write(struct run_softc *, uint8_t, uint8_t);
static int run_bbp_read(struct run_softc *, uint8_t, uint8_t *);
static int run_bbp_write(struct run_softc *, uint8_t, uint8_t);
static int run_mcu_cmd(struct run_softc *, uint8_t, uint16_t);
-static const char *run_get_rf(int);
+static const char *run_get_rf(uint16_t);
static int run_read_eeprom(struct run_softc *);
static struct ieee80211_node *run_node_alloc(struct ieee80211vap *,
const uint8_t mac[IEEE80211_ADDR_LEN]);
@@ -361,7 +364,7 @@ static void run_key_update_begin(struct ieee80211vap *);
static void run_key_update_end(struct ieee80211vap *);
static void run_key_set_cb(void *);
static int run_key_set(struct ieee80211vap *, struct ieee80211_key *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
+ const uint8_t mac[IEEE80211_ADDR_LEN]);
static void run_key_delete_cb(void *);
static int run_key_delete(struct ieee80211vap *, struct ieee80211_key *);
static void run_ratectl_to(void *);
@@ -393,6 +396,8 @@ static void run_set_rx_antenna(struct run_softc *, int);
static void run_rt2870_set_chan(struct run_softc *, u_int);
static void run_rt3070_set_chan(struct run_softc *, u_int);
static void run_rt3572_set_chan(struct run_softc *, u_int);
+static void run_rt5390_set_chan(struct run_softc *, u_int);
+static void run_rt5592_set_chan(struct run_softc *, u_int);
static int run_set_chan(struct run_softc *, struct ieee80211_channel *);
static void run_set_channel(struct ieee80211com *);
static void run_scan_start(struct ieee80211com *);
@@ -416,16 +421,19 @@ static void run_update_mcast(struct ifnet *);
static int8_t run_rssi2dbm(struct run_softc *, uint8_t, uint8_t);
static void run_update_promisc_locked(struct ifnet *);
static void run_update_promisc(struct ifnet *);
+static void run_rt5390_bbp_init(struct run_softc *);
static int run_bbp_init(struct run_softc *);
static int run_rt3070_rf_init(struct run_softc *);
+static void run_rt5390_rf_init(struct run_softc *);
static int run_rt3070_filter_calib(struct run_softc *, uint8_t, uint8_t,
uint8_t *);
static void run_rt3070_rf_setup(struct run_softc *);
static int run_txrx_enable(struct run_softc *);
+static void run_adjust_freq_offset(struct run_softc *);
static void run_init(void *);
static void run_init_locked(struct run_softc *);
static void run_stop(void *);
-static void run_delay(struct run_softc *, unsigned int);
+static void run_delay(struct run_softc *, u_int);
static const struct {
uint16_t reg;
@@ -439,6 +447,25 @@ static const struct {
uint8_t val;
} rt2860_def_bbp[] = {
RT2860_DEF_BBP
+},rt5390_def_bbp[] = {
+ RT5390_DEF_BBP
+},rt5592_def_bbp[] = {
+ RT5592_DEF_BBP
+};
+
+/*
+ * Default values for BBP register R196 for RT5592.
+ */
+static const uint8_t rt5592_bbp_r196[] = {
+ 0xe0, 0x1f, 0x38, 0x32, 0x08, 0x28, 0x19, 0x0a, 0xff, 0x00,
+ 0x16, 0x10, 0x10, 0x0b, 0x36, 0x2c, 0x26, 0x24, 0x42, 0x36,
+ 0x30, 0x2d, 0x4c, 0x46, 0x3d, 0x40, 0x3e, 0x42, 0x3d, 0x40,
+ 0x3c, 0x34, 0x2c, 0x2f, 0x3c, 0x35, 0x2e, 0x2a, 0x49, 0x41,
+ 0x36, 0x31, 0x30, 0x30, 0x0e, 0x0d, 0x28, 0x21, 0x1c, 0x16,
+ 0x50, 0x4a, 0x43, 0x40, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7d, 0x14, 0x32, 0x2c, 0x36, 0x4c, 0x43, 0x2c,
+ 0x2e, 0x36, 0x30, 0x6e
};
static const struct rfprog {
@@ -454,6 +481,15 @@ struct {
RT3070_RF3052
};
+static const struct rt5592_freqs {
+ uint16_t n;
+ uint8_t k, m, r;
+} rt5592_freqs_20mhz[] = {
+ RT5592_RF5592_20MHZ
+},rt5592_freqs_40mhz[] = {
+ RT5592_RF5592_40MHZ
+};
+
static const struct {
uint8_t reg;
uint8_t val;
@@ -461,6 +497,25 @@ static const struct {
RT3070_DEF_RF
},rt3572_def_rf[] = {
RT3572_DEF_RF
+},rt5390_def_rf[] = {
+ RT5390_DEF_RF
+},rt5392_def_rf[] = {
+ RT5392_DEF_RF
+},rt5592_def_rf[] = {
+ RT5592_DEF_RF
+},rt5592_2ghz_def_rf[] = {
+ RT5592_2GHZ_DEF_RF
+},rt5592_5ghz_def_rf[] = {
+ RT5592_5GHZ_DEF_RF
+};
+
+static const struct {
+ u_int firstchan;
+ u_int lastchan;
+ uint8_t reg;
+ uint8_t val;
+} rt5592_chan_5ghz[] = {
+ RT5592_CHAN_5GHZ
};
static const struct usb_config run_config[RUN_N_XFER] = {
@@ -557,7 +612,7 @@ run_attach(device_t self)
struct ieee80211com *ic;
struct ifnet *ifp;
uint32_t ver;
- int i, ntries, error;
+ int ntries, error;
uint8_t iface_index, bands;
device_set_usb_desc(self);
@@ -654,27 +709,11 @@ run_attach(device_t self)
bands = 0;
setbit(&bands, IEEE80211_MODE_11B);
setbit(&bands, IEEE80211_MODE_11G);
+ if (sc->rf_rev == RT2860_RF_2750 || sc->rf_rev == RT2860_RF_2850 ||
+ sc->rf_rev == RT3070_RF_3052 || sc->rf_rev == RT5592_RF_5592)
+ setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- /*
- * Do this by own because h/w supports
- * more channels than ieee80211_init_channels()
- */
- if (sc->rf_rev == RT2860_RF_2750 ||
- sc->rf_rev == RT2860_RF_2850 ||
- sc->rf_rev == RT3070_RF_3052) {
- /* set supported .11a rates */
- for (i = 14; i < N(rt2860_rf2850); i++) {
- uint8_t chan = rt2860_rf2850[i].chan;
- ic->ic_channels[ic->ic_nchans].ic_freq =
- ieee80211_ieee2mhz(chan, IEEE80211_CHAN_A);
- ic->ic_channels[ic->ic_nchans].ic_ieee = chan;
- ic->ic_channels[ic->ic_nchans].ic_flags = IEEE80211_CHAN_A;
- ic->ic_channels[ic->ic_nchans].ic_extieee = 0;
- ic->ic_nchans++;
- }
- }
-
ieee80211_ifattach(ic, sc->sc_bssid);
ic->ic_scan_start = run_scan_start;
@@ -699,7 +738,7 @@ run_attach(device_t self)
TASK_INIT(&sc->cmdq_task, 0, run_cmdq_cb, sc);
TASK_INIT(&sc->ratectl_task, 0, run_ratectl_cb, sc);
- callout_init((struct callout *)&sc->ratectl_ch, 1);
+ usb_callout_init_mtx(&sc->ratectl_ch, &sc->sc_mtx, 0);
if (bootverbose)
ieee80211_announce(ic);
@@ -803,7 +842,13 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (rvp == NULL)
return (NULL);
vap = &rvp->vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
+
+ if (ieee80211_vap_setup(ic, vap, name, unit,
+ opmode, flags, bssid, mac) != 0) {
+ /* out of memory */
+ free(rvp, M_80211_VAP);
+ return (NULL);
+ }
vap->iv_key_update_begin = run_key_update_begin;
vap->iv_key_update_end = run_key_update_end;
@@ -1009,13 +1054,12 @@ run_load_microcode(struct run_softc *sc)
/* cheap sanity check */
temp = fw->data;
bytes = *temp;
- if (bytes != be64toh(0xffffff0210280210)) {
+ if (bytes != be64toh(0xffffff0210280210ULL)) {
device_printf(sc->sc_dev, "firmware checksum failed\n");
error = EINVAL;
goto fail;
}
- run_read(sc, RT2860_ASIC_VER_ID, &tmp);
/* write microcode image */
run_write_region_1(sc, RT2870_FW_BASE, base, 4096);
run_write(sc, RT2860_H2M_MAILBOX_CID, 0xffffffff);
@@ -1062,7 +1106,7 @@ fail:
return (error);
}
-int
+static int
run_reset(struct run_softc *sc)
{
usb_device_request_t req;
@@ -1164,13 +1208,32 @@ run_write_region_1(struct run_softc *sc, uint16_t reg, const uint8_t *buf,
return (error);
#else
usb_device_request_t req;
+ int error = 0;
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = RT2870_WRITE_REGION_1;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, len);
- return (run_do_request(sc, &req, buf));
+ /*
+ * NOTE: It appears the WRITE_REGION_1 command cannot be
+ * passed a huge amount of data, which will crash the
+ * firmware. Limit amount of data passed to 64-bytes at a
+ * time.
+ */
+ while (len > 0) {
+ int delta = 64;
+ if (delta > len)
+ delta = len;
+
+ req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req.bRequest = RT2870_WRITE_REGION_1;
+ USETW(req.wValue, 0);
+ USETW(req.wIndex, reg);
+ USETW(req.wLength, delta);
+ error = run_do_request(sc, &req, __DECONST(uint8_t *, buf));
+ if (error != 0)
+ break;
+ reg += delta;
+ buf += delta;
+ len -= delta;
+ }
+ return (error);
#endif
}
@@ -1260,7 +1323,7 @@ run_srom_read(struct run_softc *sc, uint16_t addr, uint16_t *val)
}
static int
-run_rt2870_rf_write(struct run_softc *sc, uint8_t reg, uint32_t val)
+run_rt2870_rf_write(struct run_softc *sc, uint32_t val)
{
uint32_t tmp;
int error, ntries;
@@ -1274,10 +1337,7 @@ run_rt2870_rf_write(struct run_softc *sc, uint8_t reg, uint32_t val)
if (ntries == 10)
return (ETIMEDOUT);
- /* RF registers are 24-bit on the RT2860 */
- tmp = RT2860_RF_REG_CTRL | 24 << RT2860_RF_REG_WIDTH_SHIFT |
- (val & 0x3fffff) << 2 | (reg & 3);
- return (run_write(sc, RT2860_RF_CSR_CFG0, tmp));
+ return (run_write(sc, RT2860_RF_CSR_CFG0, val));
}
static int
@@ -1428,7 +1488,7 @@ b4inc(uint32_t b32, int8_t delta)
}
static const char *
-run_get_rf(int rev)
+run_get_rf(uint16_t rev)
{
switch (rev) {
case RT2860_RF_2820: return "RT2820";
@@ -1440,11 +1500,14 @@ run_get_rf(int rev)
case RT3070_RF_3021: return "RT3021";
case RT3070_RF_3022: return "RT3022";
case RT3070_RF_3052: return "RT3052";
+ case RT5592_RF_5592: return "RT5592";
+ case RT5390_RF_5370: return "RT5370";
+ case RT5390_RF_5372: return "RT5372";
}
return ("unknown");
}
-int
+static int
run_read_eeprom(struct run_softc *sc)
{
int8_t delta_2ghz, delta_5ghz;
@@ -1476,21 +1539,25 @@ run_read_eeprom(struct run_softc *sc)
sc->sc_bssid[4] = val & 0xff;
sc->sc_bssid[5] = val >> 8;
- /* read vender BBP settings */
- for (i = 0; i < 10; i++) {
- run_srom_read(sc, RT2860_EEPROM_BBP_BASE + i, &val);
- sc->bbp[i].val = val & 0xff;
- sc->bbp[i].reg = val >> 8;
- DPRINTF("BBP%d=0x%02x\n", sc->bbp[i].reg, sc->bbp[i].val);
- }
- if (sc->mac_ver >= 0x3071) {
- /* read vendor RF settings */
+ if (sc->mac_ver < 0x5390) {
+ /* read vender BBP settings */
for (i = 0; i < 10; i++) {
- run_srom_read(sc, RT3071_EEPROM_RF_BASE + i, &val);
- sc->rf[i].val = val & 0xff;
- sc->rf[i].reg = val >> 8;
- DPRINTF("RF%d=0x%02x\n", sc->rf[i].reg,
- sc->rf[i].val);
+ run_srom_read(sc, RT2860_EEPROM_BBP_BASE + i, &val);
+ sc->bbp[i].val = val & 0xff;
+ sc->bbp[i].reg = val >> 8;
+ DPRINTF("BBP%d=0x%02x\n", sc->bbp[i].reg,
+ sc->bbp[i].val);
+ }
+ if (sc->mac_ver >= 0x3071) {
+ /* read vendor RF settings */
+ for (i = 0; i < 10; i++) {
+ run_srom_read(sc, RT3071_EEPROM_RF_BASE + i,
+ &val);
+ sc->rf[i].val = val & 0xff;
+ sc->rf[i].reg = val >> 8;
+ DPRINTF("RF%d=0x%02x\n", sc->rf[i].reg,
+ sc->rf[i].val);
+ }
}
}
@@ -1516,7 +1583,11 @@ run_read_eeprom(struct run_softc *sc)
sc->leds, sc->led[0], sc->led[1], sc->led[2]);
/* read RF information */
- run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val);
+ if (sc->mac_ver == 0x5390 || sc->mac_ver ==0x5392)
+ run_srom_read(sc, 0x00, &val);
+ else
+ run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val);
+
if (val == 0xffff) {
DPRINTF("invalid EEPROM antenna info, using default\n");
if (sc->mac_ver == 0x3572) {
@@ -1536,11 +1607,15 @@ run_read_eeprom(struct run_softc *sc)
sc->nrxchains = 2;
}
} else {
- sc->rf_rev = (val >> 8) & 0xf;
+ if (sc->mac_ver == 0x5390 || sc->mac_ver ==0x5392) {
+ sc->rf_rev = val;
+ run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val);
+ } else
+ sc->rf_rev = (val >> 8) & 0xf;
sc->ntxchains = (val >> 4) & 0xf;
sc->nrxchains = val & 0xf;
}
- DPRINTF("EEPROM RF rev=0x%02x chains=%dT%dR\n",
+ DPRINTF("EEPROM RF rev=0x%04x chains=%dT%dR\n",
sc->rf_rev, sc->ntxchains, sc->nrxchains);
/* check if RF supports automatic Tx access gain control */
@@ -1564,16 +1639,29 @@ run_read_eeprom(struct run_softc *sc)
sc->txpow1[i + 0] = (int8_t)(val & 0xff);
sc->txpow1[i + 1] = (int8_t)(val >> 8);
- run_srom_read(sc, RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2, &val);
- sc->txpow2[i + 0] = (int8_t)(val & 0xff);
- sc->txpow2[i + 1] = (int8_t)(val >> 8);
+ if (sc->mac_ver != 0x5390) {
+ run_srom_read(sc,
+ RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2, &val);
+ sc->txpow2[i + 0] = (int8_t)(val & 0xff);
+ sc->txpow2[i + 1] = (int8_t)(val >> 8);
+ }
}
/* fix broken Tx power entries */
for (i = 0; i < 14; i++) {
- if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31)
- sc->txpow1[i] = 5;
- if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31)
- sc->txpow2[i] = 5;
+ if (sc->mac_ver >= 0x5390) {
+ if (sc->txpow1[i] < 0 || sc->txpow1[i] > 27)
+ sc->txpow1[i] = 5;
+ } else {
+ if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31)
+ sc->txpow1[i] = 5;
+ }
+ if (sc->mac_ver > 0x5390) {
+ if (sc->txpow2[i] < 0 || sc->txpow2[i] > 27)
+ sc->txpow2[i] = 5;
+ } else if (sc->mac_ver < 0x5390) {
+ if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31)
+ sc->txpow2[i] = 5;
+ }
DPRINTF("chan %d: power1=%d, power2=%d\n",
rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i]);
}
@@ -1588,11 +1676,13 @@ run_read_eeprom(struct run_softc *sc)
sc->txpow2[i + 15] = (int8_t)(val >> 8);
}
/* fix broken Tx power entries */
- for (i = 0; i < 40; i++) {
- if (sc->txpow1[14 + i] < -7 || sc->txpow1[14 + i] > 15)
- sc->txpow1[14 + i] = 5;
- if (sc->txpow2[14 + i] < -7 || sc->txpow2[14 + i] > 15)
- sc->txpow2[14 + i] = 5;
+ for (i = 0; i < 40; i++ ) {
+ if (sc->mac_ver != 0x5592) {
+ if (sc->txpow1[14 + i] < -7 || sc->txpow1[14 + i] > 15)
+ sc->txpow1[14 + i] = 5;
+ if (sc->txpow2[14 + i] < -7 || sc->txpow2[14 + i] > 15)
+ sc->txpow2[14 + i] = 5;
+ }
DPRINTF("chan %d: power1=%d, power2=%d\n",
rt2860_rf2850[14 + i].chan, sc->txpow1[14 + i],
sc->txpow2[14 + i]);
@@ -2236,8 +2326,10 @@ run_ratectl_cb(void *arg, int pending)
ieee80211_iterate_nodes(&ic->ic_sta, run_iter_func, sc);
}
+ RUN_LOCK(sc);
if(sc->ratectl_run != RUN_RATECTL_OFF)
usb_callout_reset(&sc->ratectl_ch, hz, run_ratectl_to, sc);
+ RUN_UNLOCK(sc);
}
static void
@@ -2472,12 +2564,15 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
struct rt2870_rxd *rxd;
struct rt2860_rxwi *rxwi;
uint32_t flags;
- uint16_t len, phy;
+ uint16_t len, rxwisize;
uint8_t ant, rssi;
int8_t nf;
rxwi = mtod(m, struct rt2860_rxwi *);
len = le16toh(rxwi->len) & 0xfff;
+ rxwisize = (sc->mac_ver == 0x5592) ?
+ sizeof(struct rt2860_rxwi) + sizeof(uint64_t) :
+ sizeof(struct rt2860_rxwi);
if (__predict_false(len > dmalen)) {
m_freem(m);
ifp->if_ierrors++;
@@ -2495,8 +2590,8 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
return;
}
- m->m_data += sizeof(struct rt2860_rxwi);
- m->m_pkthdr.len = m->m_len -= sizeof(struct rt2860_rxwi);
+ m->m_data += rxwisize;
+ m->m_pkthdr.len = m->m_len -= rxwisize;
wh = mtod(m, struct ieee80211_frame *);
@@ -2516,7 +2611,8 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
if (__predict_false(flags & RT2860_RX_MICERR)) {
/* report MIC failures to net80211 for TKIP */
if (ni != NULL)
- ieee80211_notify_michael_failure(ni->ni_vap, wh, rxwi->keyidx);
+ ieee80211_notify_michael_failure(ni->ni_vap, wh,
+ rxwi->keyidx);
m_freem(m);
ifp->if_ierrors++;
DPRINTF("MIC error. Someone is lying.\n");
@@ -2539,6 +2635,7 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
if (__predict_false(ieee80211_radiotap_active(ic))) {
struct run_rx_radiotap_header *tap = &sc->sc_rxtap;
+ uint16_t phy;
tap->wr_flags = 0;
tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
@@ -2583,8 +2680,13 @@ run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
struct mbuf *m = NULL;
struct mbuf *m0;
uint32_t dmalen;
+ uint16_t rxwisize;
int xferlen;
+ rxwisize = (sc->mac_ver == 0x5592) ?
+ sizeof(struct rt2860_rxwi) + sizeof(uint64_t) :
+ sizeof(struct rt2860_rxwi);
+
usbd_xfer_status(xfer, &xferlen, NULL, NULL, NULL);
switch (USB_GET_STATE(xfer)) {
@@ -2592,8 +2694,8 @@ run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
DPRINTFN(15, "rx done, actlen=%d\n", xferlen);
- if (xferlen < (int)(sizeof(uint32_t) +
- sizeof(struct rt2860_rxwi) + sizeof(struct rt2870_rxd))) {
+ if (xferlen < (int)(sizeof(uint32_t) + rxwisize +
+ sizeof(struct rt2870_rxd))) {
DPRINTF("xfer too short %d\n", xferlen);
goto tr_setup;
}
@@ -2675,6 +2777,7 @@ tr_setup:
m->m_data += 4;
m->m_pkthdr.len = m->m_len -= 4;
run_rx_frame(sc, m, dmalen);
+ m = NULL; /* don't free source buffer */
break;
}
@@ -2696,6 +2799,9 @@ tr_setup:
m->m_pkthdr.len = m->m_len -= dmalen + 8;
}
+ /* make sure we free the source buffer, if any */
+ m_freem(m);
+
RUN_LOCK(sc);
}
@@ -2723,7 +2829,7 @@ run_tx_free(struct run_endpoint_queue *pq,
}
static void
-run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, unsigned int index)
+run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, u_int index)
{
struct run_softc *sc = usbd_xfer_softc(xfer);
struct ifnet *ifp = sc->sc_ifp;
@@ -2763,8 +2869,10 @@ tr_setup:
STAILQ_REMOVE_HEAD(&pq->tx_qh, next);
m = data->m;
+ size = (sc->mac_ver == 0x5592) ?
+ RUN_MAX_TXSZ + sizeof(uint32_t) : RUN_MAX_TXSZ;
if ((m->m_pkthdr.len +
- sizeof(data->desc) + 3 + 8) > RUN_MAX_TXSZ) {
+ sizeof(data->desc) + 3 + 8) > size) {
DPRINTF("data overflow, %u bytes\n",
m->m_pkthdr.len);
@@ -2776,7 +2884,8 @@ tr_setup:
}
pc = usbd_xfer_get_frame(xfer, 0);
- size = sizeof(data->desc);
+ size = (sc->mac_ver == 0x5592) ?
+ sizeof(data->desc) + sizeof(uint32_t) : sizeof(data->desc);
usbd_copy_in(pc, 0, &data->desc, size);
usbd_m_copy_in(pc, size, m, 0, m->m_pkthdr.len);
size += m->m_pkthdr.len;
@@ -2791,9 +2900,8 @@ tr_setup:
vap = data->ni->ni_vap;
if (ieee80211_radiotap_active_vap(vap)) {
struct run_tx_radiotap_header *tap = &sc->sc_txtap;
- struct rt2860_txwi *txwi =
+ struct rt2860_txwi *txwi =
(struct rt2860_txwi *)(&data->desc + sizeof(struct rt2870_txd));
-
tap->wt_flags = 0;
tap->wt_rate = rt2860_rates[data->ridx].rate;
tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
@@ -2903,7 +3011,7 @@ run_set_tx_desc(struct run_softc *sc, struct run_tx_data *data)
struct ieee80211_frame *wh;
struct rt2870_txd *txd;
struct rt2860_txwi *txwi;
- uint16_t xferlen;
+ uint16_t xferlen, txwisize;
uint16_t mcs;
uint8_t ridx = data->ridx;
uint8_t pad;
@@ -2911,7 +3019,9 @@ run_set_tx_desc(struct run_softc *sc, struct run_tx_data *data)
/* get MCS code from rate index */
mcs = rt2860_rates[ridx].mcs;
- xferlen = sizeof(*txwi) + m->m_pkthdr.len;
+ txwisize = (sc->mac_ver == 0x5592) ?
+ sizeof(*txwi) + sizeof(uint32_t) : sizeof(*txwi);
+ xferlen = txwisize + m->m_pkthdr.len;
/* roundup to 32-bit alignment */
xferlen = (xferlen + 3) & ~3;
@@ -3037,7 +3147,7 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
dur = rt2860_rates[ctl_ridx].sp_ack_dur;
else
dur = rt2860_rates[ctl_ridx].lp_ack_dur;
- *(uint16_t *)wh->i_dur = htole16(dur);
+ USETW(wh->i_dur, dur);
}
/* reserve slots for mgmt packets, just in case */
@@ -3054,12 +3164,12 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
txd->flags = qflags;
txwi = (struct rt2860_txwi *)(txd + 1);
txwi->xflags = xflags;
- if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+ if (IEEE80211_IS_MULTICAST(wh->i_addr1))
txwi->wcid = 0;
- } else {
+ else
txwi->wcid = (vap->iv_opmode == IEEE80211_M_STA) ?
1 : RUN_AID2WCID(ni->ni_associd);
- }
+
/* clear leftover garbage bits */
txwi->flags = 0;
txwi->txop = 0;
@@ -3117,9 +3227,9 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
usbd_transfer_start(sc->sc_xfer[qid]);
- DPRINTFN(8, "sending data frame len=%d rate=%d qid=%d\n", m->m_pkthdr.len +
- (int)(sizeof (struct rt2870_txd) + sizeof (struct rt2860_rxwi)),
- rt2860_rates[ridx].rate, qid);
+ DPRINTFN(8, "sending data frame len=%d rate=%d qid=%d\n",
+ m->m_pkthdr.len + (int)(sizeof(struct rt2870_txd) +
+ sizeof(struct rt2860_txwi)), rt2860_rates[ridx].rate, qid);
return (0);
}
@@ -3156,7 +3266,7 @@ run_tx_mgt(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
dur = ieee80211_ack_duration(ic->ic_rt, rt2860_rates[ridx].rate,
ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- *(uint16_t *)wh->i_dur = htole16(dur);
+ USETW(wh->i_dur, dur);
}
if (sc->sc_epq[0].tx_nfree == 0) {
@@ -3183,7 +3293,7 @@ run_tx_mgt(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
run_set_tx_desc(sc, data);
DPRINTFN(10, "sending mgt frame len=%d rate=%d\n", m->m_pkthdr.len +
- (int)(sizeof (struct rt2870_txd) + sizeof (struct rt2860_rxwi)),
+ (int)(sizeof(struct rt2870_txd) + sizeof(struct rt2860_txwi)),
rt2860_rates[ridx].rate);
STAILQ_INSERT_TAIL(&sc->sc_epq[0].tx_qh, data, next);
@@ -3513,18 +3623,63 @@ run_select_chan_group(struct run_softc *sc, int group)
run_bbp_write(sc, 62, 0x37 - sc->lna[group]);
run_bbp_write(sc, 63, 0x37 - sc->lna[group]);
run_bbp_write(sc, 64, 0x37 - sc->lna[group]);
- run_bbp_write(sc, 86, 0x00);
+ if (sc->mac_ver < 0x3572)
+ run_bbp_write(sc, 86, 0x00);
if (group == 0) {
if (sc->ext_2ghz_lna) {
- run_bbp_write(sc, 82, 0x62);
- run_bbp_write(sc, 75, 0x46);
+ if (sc->mac_ver >= 0x5390)
+ run_bbp_write(sc, 75, 0x52);
+ else {
+ run_bbp_write(sc, 82, 0x62);
+ run_bbp_write(sc, 75, 0x46);
+ }
} else {
- run_bbp_write(sc, 82, 0x84);
- run_bbp_write(sc, 75, 0x50);
+ if (sc->mac_ver == 0x5592) {
+ run_bbp_write(sc, 79, 0x1c);
+ run_bbp_write(sc, 80, 0x0e);
+ run_bbp_write(sc, 81, 0x3a);
+ run_bbp_write(sc, 82, 0x62);
+
+ run_bbp_write(sc, 195, 0x80);
+ run_bbp_write(sc, 196, 0xe0);
+ run_bbp_write(sc, 195, 0x81);
+ run_bbp_write(sc, 196, 0x1f);
+ run_bbp_write(sc, 195, 0x82);
+ run_bbp_write(sc, 196, 0x38);
+ run_bbp_write(sc, 195, 0x83);
+ run_bbp_write(sc, 196, 0x32);
+ run_bbp_write(sc, 195, 0x85);
+ run_bbp_write(sc, 196, 0x28);
+ run_bbp_write(sc, 195, 0x86);
+ run_bbp_write(sc, 196, 0x19);
+ } else if (sc->mac_ver >= 0x5390)
+ run_bbp_write(sc, 75, 0x50);
+ else {
+ run_bbp_write(sc, 82, 0x84);
+ run_bbp_write(sc, 75, 0x50);
+ }
}
} else {
- if (sc->mac_ver == 0x3572)
+ if (sc->mac_ver == 0x5592) {
+ run_bbp_write(sc, 79, 0x18);
+ run_bbp_write(sc, 80, 0x08);
+ run_bbp_write(sc, 81, 0x38);
+ run_bbp_write(sc, 82, 0x92);
+
+ run_bbp_write(sc, 195, 0x80);
+ run_bbp_write(sc, 196, 0xf0);
+ run_bbp_write(sc, 195, 0x81);
+ run_bbp_write(sc, 196, 0x1e);
+ run_bbp_write(sc, 195, 0x82);
+ run_bbp_write(sc, 196, 0x28);
+ run_bbp_write(sc, 195, 0x83);
+ run_bbp_write(sc, 196, 0x20);
+ run_bbp_write(sc, 195, 0x85);
+ run_bbp_write(sc, 196, 0x7f);
+ run_bbp_write(sc, 195, 0x86);
+ run_bbp_write(sc, 196, 0x7f);
+ } else if (sc->mac_ver == 0x3572)
run_bbp_write(sc, 82, 0x94);
else
run_bbp_write(sc, 82, 0xf2);
@@ -3559,6 +3714,11 @@ run_select_chan_group(struct run_softc *sc, int group)
} else
run_write(sc, RT2860_TX_PIN_CFG, tmp);
+ if (sc->mac_ver == 0x5592) {
+ run_bbp_write(sc, 195, 0x8d);
+ run_bbp_write(sc, 196, 0x1a);
+ }
+
/* set initial AGC value */
if (group == 0) { /* 2GHz band */
if (sc->mac_ver >= 0x3070)
@@ -3566,7 +3726,9 @@ run_select_chan_group(struct run_softc *sc, int group)
else
agc = 0x2e + sc->lna[0];
} else { /* 5GHz band */
- if (sc->mac_ver == 0x3572)
+ if (sc->mac_ver == 0x5592)
+ agc = 0x24 + sc->lna[group] * 2;
+ else if (sc->mac_ver == 0x3572)
agc = 0x22 + (sc->lna[group] * 5) / 3;
else
agc = 0x32 + (sc->lna[group] * 5) / 3;
@@ -3575,7 +3737,7 @@ run_select_chan_group(struct run_softc *sc, int group)
}
static void
-run_rt2870_set_chan(struct run_softc *sc, uint32_t chan)
+run_rt2870_set_chan(struct run_softc *sc, u_int chan)
{
const struct rfprog *rfprog = rt2860_rf2850;
uint32_t r2, r3, r4;
@@ -3587,58 +3749,71 @@ run_rt2870_set_chan(struct run_softc *sc, uint32_t chan)
r2 = rfprog[i].r2;
if (sc->ntxchains == 1)
- r2 |= 1 << 12; /* 1T: disable Tx chain 2 */
+ r2 |= 1 << 14; /* 1T: disable Tx chain 2 */
if (sc->nrxchains == 1)
- r2 |= 1 << 15 | 1 << 4; /* 1R: disable Rx chains 2 & 3 */
+ r2 |= 1 << 17 | 1 << 6; /* 1R: disable Rx chains 2 & 3 */
else if (sc->nrxchains == 2)
- r2 |= 1 << 4; /* 2R: disable Rx chain 3 */
+ r2 |= 1 << 6; /* 2R: disable Rx chain 3 */
/* use Tx power values from EEPROM */
txpow1 = sc->txpow1[i];
txpow2 = sc->txpow2[i];
+
+ /* Initialize RF R3 and R4. */
+ r3 = rfprog[i].r3 & 0xffffc1ff;
+ r4 = (rfprog[i].r4 & ~(0x001f87c0)) | (sc->freq << 15);
if (chan > 14) {
- if (txpow1 >= 0)
- txpow1 = txpow1 << 1 | 1;
- else
- txpow1 = (7 + txpow1) << 1;
- if (txpow2 >= 0)
- txpow2 = txpow2 << 1 | 1;
- else
- txpow2 = (7 + txpow2) << 1;
+ if (txpow1 >= 0) {
+ txpow1 = (txpow1 > 0xf) ? (0xf) : (txpow1);
+ r3 |= (txpow1 << 10) | (1 << 9);
+ } else {
+ txpow1 += 7;
+
+ /* txpow1 is not possible larger than 15. */
+ r3 |= (txpow1 << 10);
+ }
+ if (txpow2 >= 0) {
+ txpow2 = (txpow2 > 0xf) ? (0xf) : (txpow2);
+ r4 |= (txpow2 << 7) | (1 << 6);
+ } else {
+ txpow2 += 7;
+ r4 |= (txpow2 << 7);
+ }
+ } else {
+ /* Set Tx0 power. */
+ r3 |= (txpow1 << 9);
+
+ /* Set frequency offset and Tx1 power. */
+ r4 |= (txpow2 << 6);
}
- r3 = rfprog[i].r3 | txpow1 << 7;
- r4 = rfprog[i].r4 | sc->freq << 13 | txpow2 << 4;
- run_rt2870_rf_write(sc, RT2860_RF1, rfprog[i].r1);
- run_rt2870_rf_write(sc, RT2860_RF2, r2);
- run_rt2870_rf_write(sc, RT2860_RF3, r3);
- run_rt2870_rf_write(sc, RT2860_RF4, r4);
+ run_rt2870_rf_write(sc, rfprog[i].r1);
+ run_rt2870_rf_write(sc, r2);
+ run_rt2870_rf_write(sc, r3 & ~(1 << 2));
+ run_rt2870_rf_write(sc, r4);
run_delay(sc, 10);
- run_rt2870_rf_write(sc, RT2860_RF1, rfprog[i].r1);
- run_rt2870_rf_write(sc, RT2860_RF2, r2);
- run_rt2870_rf_write(sc, RT2860_RF3, r3 | 1);
- run_rt2870_rf_write(sc, RT2860_RF4, r4);
+ run_rt2870_rf_write(sc, rfprog[i].r1);
+ run_rt2870_rf_write(sc, r2);
+ run_rt2870_rf_write(sc, r3 | (1 << 2));
+ run_rt2870_rf_write(sc, r4);
run_delay(sc, 10);
- run_rt2870_rf_write(sc, RT2860_RF1, rfprog[i].r1);
- run_rt2870_rf_write(sc, RT2860_RF2, r2);
- run_rt2870_rf_write(sc, RT2860_RF3, r3);
- run_rt2870_rf_write(sc, RT2860_RF4, r4);
+ run_rt2870_rf_write(sc, rfprog[i].r1);
+ run_rt2870_rf_write(sc, r2);
+ run_rt2870_rf_write(sc, r3 & ~(1 << 2));
+ run_rt2870_rf_write(sc, r4);
}
static void
-run_rt3070_set_chan(struct run_softc *sc, uint32_t chan)
+run_rt3070_set_chan(struct run_softc *sc, u_int chan)
{
int8_t txpow1, txpow2;
uint8_t rf;
int i;
- /* RT3070 is 2GHz only */
- KASSERT(chan >= 1 && chan <= 14, ("wrong channel selected\n"));
-
/* find the settings for this channel (we know it exists) */
for (i = 0; rt2860_rf2850[i].chan != chan; i++);
@@ -3647,7 +3822,12 @@ run_rt3070_set_chan(struct run_softc *sc, uint32_t chan)
txpow2 = sc->txpow2[i];
run_rt3070_rf_write(sc, 2, rt3070_freqs[i].n);
- run_rt3070_rf_write(sc, 3, rt3070_freqs[i].k);
+
+ /* RT3370/RT3390: RF R3 [7:4] is not reserved bits. */
+ run_rt3070_rf_read(sc, 3, &rf);
+ rf = (rf & ~0x0f) | rt3070_freqs[i].k;
+ run_rt3070_rf_write(sc, 3, rf);
+
run_rt3070_rf_read(sc, 6, &rf);
rf = (rf & ~0x03) | rt3070_freqs[i].r;
run_rt3070_rf_write(sc, 6, rf);
@@ -3843,18 +4023,276 @@ run_rt3572_set_chan(struct run_softc *sc, u_int chan)
}
static void
+run_rt5390_set_chan(struct run_softc *sc, u_int chan)
+{
+ int8_t txpow1, txpow2;
+ uint8_t rf;
+ int i;
+
+ /* find the settings for this channel (we know it exists) */
+ for (i = 0; rt2860_rf2850[i].chan != chan; i++);
+
+ /* use Tx power values from EEPROM */
+ txpow1 = sc->txpow1[i];
+ txpow2 = sc->txpow2[i];
+
+ run_rt3070_rf_write(sc, 8, rt3070_freqs[i].n);
+ run_rt3070_rf_write(sc, 9, rt3070_freqs[i].k & 0x0f);
+ run_rt3070_rf_read(sc, 11, &rf);
+ rf = (rf & ~0x03) | (rt3070_freqs[i].r & 0x03);
+ run_rt3070_rf_write(sc, 11, rf);
+
+ run_rt3070_rf_read(sc, 49, &rf);
+ rf = (rf & ~0x3f) | (txpow1 & 0x3f);
+ /* The valid range of the RF R49 is 0x00 to 0x27. */
+ if ((rf & 0x3f) > 0x27)
+ rf = (rf & ~0x3f) | 0x27;
+ run_rt3070_rf_write(sc, 49, rf);
+
+ if (sc->mac_ver == 0x5392) {
+ run_rt3070_rf_read(sc, 50, &rf);
+ rf = (rf & ~0x3f) | (txpow2 & 0x3f);
+ /* The valid range of the RF R50 is 0x00 to 0x27. */
+ if ((rf & 0x3f) > 0x27)
+ rf = (rf & ~0x3f) | 0x27;
+ run_rt3070_rf_write(sc, 50, rf);
+ }
+
+ run_rt3070_rf_read(sc, 1, &rf);
+ rf |= RT3070_RF_BLOCK | RT3070_PLL_PD | RT3070_RX0_PD | RT3070_TX0_PD;
+ if (sc->mac_ver == 0x5392)
+ rf |= RT3070_RX1_PD | RT3070_TX1_PD;
+ run_rt3070_rf_write(sc, 1, rf);
+
+ if (sc->mac_ver != 0x5392) {
+ run_rt3070_rf_read(sc, 2, &rf);
+ rf |= 0x80;
+ run_rt3070_rf_write(sc, 2, rf);
+ run_delay(sc, 10);
+ rf &= 0x7f;
+ run_rt3070_rf_write(sc, 2, rf);
+ }
+
+ run_adjust_freq_offset(sc);
+
+ if (sc->mac_ver == 0x5392) {
+ /* Fix for RT5392C. */
+ if (sc->mac_rev >= 0x0223) {
+ if (chan <= 4)
+ rf = 0x0f;
+ else if (chan >= 5 && chan <= 7)
+ rf = 0x0e;
+ else
+ rf = 0x0d;
+ run_rt3070_rf_write(sc, 23, rf);
+
+ if (chan <= 4)
+ rf = 0x0c;
+ else if (chan == 5)
+ rf = 0x0b;
+ else if (chan >= 6 && chan <= 7)
+ rf = 0x0a;
+ else if (chan >= 8 && chan <= 10)
+ rf = 0x09;
+ else
+ rf = 0x08;
+ run_rt3070_rf_write(sc, 59, rf);
+ } else {
+ if (chan <= 11)
+ rf = 0x0f;
+ else
+ rf = 0x0b;
+ run_rt3070_rf_write(sc, 59, rf);
+ }
+ } else {
+ /* Fix for RT5390F. */
+ if (sc->mac_rev >= 0x0502) {
+ if (chan <= 11)
+ rf = 0x43;
+ else
+ rf = 0x23;
+ run_rt3070_rf_write(sc, 55, rf);
+
+ if (chan <= 11)
+ rf = 0x0f;
+ else if (chan == 12)
+ rf = 0x0d;
+ else
+ rf = 0x0b;
+ run_rt3070_rf_write(sc, 59, rf);
+ } else {
+ run_rt3070_rf_write(sc, 55, 0x44);
+ run_rt3070_rf_write(sc, 59, 0x8f);
+ }
+ }
+
+ /* Enable VCO calibration. */
+ run_rt3070_rf_read(sc, 3, &rf);
+ rf |= RT5390_VCOCAL;
+ run_rt3070_rf_write(sc, 3, rf);
+}
+
+static void
+run_rt5592_set_chan(struct run_softc *sc, u_int chan)
+{
+ const struct rt5592_freqs *freqs;
+ uint32_t tmp;
+ uint8_t reg, rf, txpow_bound;
+ int8_t txpow1, txpow2;
+ int i;
+
+ run_read(sc, RT5592_DEBUG_INDEX, &tmp);
+ freqs = (tmp & RT5592_SEL_XTAL) ?
+ rt5592_freqs_40mhz : rt5592_freqs_20mhz;
+
+ /* find the settings for this channel (we know it exists) */
+ for (i = 0; rt2860_rf2850[i].chan != chan; i++, freqs++);
+
+ /* use Tx power values from EEPROM */
+ txpow1 = sc->txpow1[i];
+ txpow2 = sc->txpow2[i];
+
+ run_read(sc, RT3070_LDO_CFG0, &tmp);
+ tmp &= ~0x1c000000;
+ if (chan > 14)
+ tmp |= 0x14000000;
+ run_write(sc, RT3070_LDO_CFG0, tmp);
+
+ /* N setting. */
+ run_rt3070_rf_write(sc, 8, freqs->n & 0xff);
+ run_rt3070_rf_read(sc, 9, &rf);
+ rf &= ~(1 << 4);
+ rf |= ((freqs->n & 0x0100) >> 8) << 4;
+ run_rt3070_rf_write(sc, 9, rf);
+
+ /* K setting. */
+ run_rt3070_rf_read(sc, 9, &rf);
+ rf &= ~0x0f;
+ rf |= (freqs->k & 0x0f);
+ run_rt3070_rf_write(sc, 9, rf);
+
+ /* Mode setting. */
+ run_rt3070_rf_read(sc, 11, &rf);
+ rf &= ~0x0c;
+ rf |= ((freqs->m - 0x8) & 0x3) << 2;
+ run_rt3070_rf_write(sc, 11, rf);
+ run_rt3070_rf_read(sc, 9, &rf);
+ rf &= ~(1 << 7);
+ rf |= (((freqs->m - 0x8) & 0x4) >> 2) << 7;
+ run_rt3070_rf_write(sc, 9, rf);
+
+ /* R setting. */
+ run_rt3070_rf_read(sc, 11, &rf);
+ rf &= ~0x03;
+ rf |= (freqs->r - 0x1);
+ run_rt3070_rf_write(sc, 11, rf);
+
+ if (chan <= 14) {
+ /* Initialize RF registers for 2GHZ. */
+ for (i = 0; i < nitems(rt5592_2ghz_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt5592_2ghz_def_rf[i].reg,
+ rt5592_2ghz_def_rf[i].val);
+ }
+
+ rf = (chan <= 10) ? 0x07 : 0x06;
+ run_rt3070_rf_write(sc, 23, rf);
+ run_rt3070_rf_write(sc, 59, rf);
+
+ run_rt3070_rf_write(sc, 55, 0x43);
+
+ /*
+ * RF R49/R50 Tx power ALC code.
+ * G-band bit<7:6>=1:0, bit<5:0> range from 0x0 ~ 0x27.
+ */
+ reg = 2;
+ txpow_bound = 0x27;
+ } else {
+ /* Initialize RF registers for 5GHZ. */
+ for (i = 0; i < nitems(rt5592_5ghz_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt5592_5ghz_def_rf[i].reg,
+ rt5592_5ghz_def_rf[i].val);
+ }
+ for (i = 0; i < nitems(rt5592_chan_5ghz); i++) {
+ if (chan >= rt5592_chan_5ghz[i].firstchan &&
+ chan <= rt5592_chan_5ghz[i].lastchan) {
+ run_rt3070_rf_write(sc, rt5592_chan_5ghz[i].reg,
+ rt5592_chan_5ghz[i].val);
+ }
+ }
+
+ /*
+ * RF R49/R50 Tx power ALC code.
+ * A-band bit<7:6>=1:1, bit<5:0> range from 0x0 ~ 0x2b.
+ */
+ reg = 3;
+ txpow_bound = 0x2b;
+ }
+
+ /* RF R49 ch0 Tx power ALC code. */
+ run_rt3070_rf_read(sc, 49, &rf);
+ rf &= ~0xc0;
+ rf |= (reg << 6);
+ rf = (rf & ~0x3f) | (txpow1 & 0x3f);
+ if ((rf & 0x3f) > txpow_bound)
+ rf = (rf & ~0x3f) | txpow_bound;
+ run_rt3070_rf_write(sc, 49, rf);
+
+ /* RF R50 ch1 Tx power ALC code. */
+ run_rt3070_rf_read(sc, 50, &rf);
+ rf &= ~(1 << 7 | 1 << 6);
+ rf |= (reg << 6);
+ rf = (rf & ~0x3f) | (txpow2 & 0x3f);
+ if ((rf & 0x3f) > txpow_bound)
+ rf = (rf & ~0x3f) | txpow_bound;
+ run_rt3070_rf_write(sc, 50, rf);
+
+ /* Enable RF_BLOCK, PLL_PD, RX0_PD, and TX0_PD. */
+ run_rt3070_rf_read(sc, 1, &rf);
+ rf |= (RT3070_RF_BLOCK | RT3070_PLL_PD | RT3070_RX0_PD | RT3070_TX0_PD);
+ if (sc->ntxchains > 1)
+ rf |= RT3070_TX1_PD;
+ if (sc->nrxchains > 1)
+ rf |= RT3070_RX1_PD;
+ run_rt3070_rf_write(sc, 1, rf);
+
+ run_rt3070_rf_write(sc, 6, 0xe4);
+
+ run_rt3070_rf_write(sc, 30, 0x10);
+ run_rt3070_rf_write(sc, 31, 0x80);
+ run_rt3070_rf_write(sc, 32, 0x80);
+
+ run_adjust_freq_offset(sc);
+
+ /* Enable VCO calibration. */
+ run_rt3070_rf_read(sc, 3, &rf);
+ rf |= RT5390_VCOCAL;
+ run_rt3070_rf_write(sc, 3, rf);
+}
+
+static void
run_set_rx_antenna(struct run_softc *sc, int aux)
{
uint32_t tmp;
+ uint8_t bbp152;
if (aux) {
- run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 0);
- run_read(sc, RT2860_GPIO_CTRL, &tmp);
- run_write(sc, RT2860_GPIO_CTRL, (tmp & ~0x0808) | 0x08);
+ if (sc->rf_rev == RT5390_RF_5370) {
+ run_bbp_read(sc, 152, &bbp152);
+ run_bbp_write(sc, 152, bbp152 & ~0x80);
+ } else {
+ run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 0);
+ run_read(sc, RT2860_GPIO_CTRL, &tmp);
+ run_write(sc, RT2860_GPIO_CTRL, (tmp & ~0x0808) | 0x08);
+ }
} else {
- run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 1);
- run_read(sc, RT2860_GPIO_CTRL, &tmp);
- run_write(sc, RT2860_GPIO_CTRL, tmp & ~0x0808);
+ if (sc->rf_rev == RT5390_RF_5370) {
+ run_bbp_read(sc, 152, &bbp152);
+ run_bbp_write(sc, 152, bbp152 | 0x80);
+ } else {
+ run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 1);
+ run_read(sc, RT2860_GPIO_CTRL, &tmp);
+ run_write(sc, RT2860_GPIO_CTRL, tmp & ~0x0808);
+ }
}
}
@@ -3862,13 +4300,17 @@ static int
run_set_chan(struct run_softc *sc, struct ieee80211_channel *c)
{
struct ieee80211com *ic = sc->sc_ifp->if_l2com;
- uint32_t chan, group;
+ u_int chan, group;
chan = ieee80211_chan2ieee(ic, c);
if (chan == 0 || chan == IEEE80211_CHAN_ANY)
return (EINVAL);
- if (sc->mac_ver == 0x3572)
+ if (sc->mac_ver == 0x5592)
+ run_rt5592_set_chan(sc, chan);
+ else if (sc->mac_ver >= 0x5390)
+ run_rt5390_set_chan(sc, chan);
+ else if (sc->mac_ver == 0x3572)
run_rt3572_set_chan(sc, chan);
else if (sc->mac_ver >= 0x3070)
run_rt3070_set_chan(sc, chan);
@@ -3991,6 +4433,7 @@ run_update_beacon_cb(void *arg)
struct run_softc *sc = ic->ic_ifp->if_softc;
struct rt2860_txwi txwi;
struct mbuf *m;
+ uint16_t txwisize;
uint8_t ridx;
if (vap->iv_bss->ni_chan == IEEE80211_CHAN_ANYC)
@@ -4010,25 +4453,26 @@ run_update_beacon_cb(void *arg)
}
m = rvp->beacon_mbuf;
- memset(&txwi, 0, sizeof txwi);
+ memset(&txwi, 0, sizeof(txwi));
txwi.wcid = 0xff;
txwi.len = htole16(m->m_pkthdr.len);
+
/* send beacons at the lowest available rate */
ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
RT2860_RIDX_OFDM6 : RT2860_RIDX_CCK1;
txwi.phy = htole16(rt2860_rates[ridx].mcs);
if (rt2860_rates[ridx].phy == IEEE80211_T_OFDM)
- txwi.phy |= htole16(RT2860_PHY_OFDM);
+ txwi.phy |= htole16(RT2860_PHY_OFDM);
txwi.txop = RT2860_TX_TXOP_HT;
txwi.flags = RT2860_TX_TS;
txwi.xflags = RT2860_TX_NSEQ;
- run_write_region_1(sc, RT2860_BCN_BASE(rvp->rvp_id),
- (uint8_t *)&txwi, sizeof txwi);
- run_write_region_1(sc, RT2860_BCN_BASE(rvp->rvp_id) + sizeof txwi,
- mtod(m, uint8_t *), (m->m_pkthdr.len + 1) & ~1); /* roundup len */
-
- return;
+ txwisize = (sc->mac_ver == 0x5592) ?
+ sizeof(txwi) + sizeof(uint32_t) : sizeof(txwi);
+ run_write_region_1(sc, RT2860_BCN_BASE(rvp->rvp_id), (uint8_t *)&txwi,
+ txwisize);
+ run_write_region_1(sc, RT2860_BCN_BASE(rvp->rvp_id) + txwisize,
+ mtod(m, uint8_t *), (m->m_pkthdr.len + 1) & ~1);
}
static void
@@ -4148,7 +4592,8 @@ run_enable_tsf_sync(struct run_softc *sc)
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
- DPRINTF("rvp_id=%d ic_opmode=%d\n", RUN_VAP(vap)->rvp_id, ic->ic_opmode);
+ DPRINTF("rvp_id=%d ic_opmode=%d\n", RUN_VAP(vap)->rvp_id,
+ ic->ic_opmode);
run_read(sc, RT2860_BCN_TIME_CFG, &tmp);
tmp &= ~0x1fffff;
@@ -4304,7 +4749,7 @@ run_rssi2dbm(struct run_softc *sc, uint8_t rssi, uint8_t rxchain)
int delta;
if (IEEE80211_IS_CHAN_5GHZ(c)) {
- uint32_t chan = ieee80211_chan2ieee(ic, c);
+ u_int chan = ieee80211_chan2ieee(ic, c);
delta = sc->rssi_5ghz[rxchain];
/* determine channel group */
@@ -4320,6 +4765,64 @@ run_rssi2dbm(struct run_softc *sc, uint8_t rssi, uint8_t rxchain)
return (-12 - delta - rssi);
}
+static void
+run_rt5390_bbp_init(struct run_softc *sc)
+{
+ int i;
+ uint8_t bbp;
+
+ /* Apply maximum likelihood detection for 2 stream case. */
+ run_bbp_read(sc, 105, &bbp);
+ if (sc->nrxchains > 1)
+ run_bbp_write(sc, 105, bbp | RT5390_MLD);
+
+ /* Avoid data lost and CRC error. */
+ run_bbp_read(sc, 4, &bbp);
+ run_bbp_write(sc, 4, bbp | RT5390_MAC_IF_CTRL);
+
+ if (sc->mac_ver == 0x5592) {
+ for (i = 0; i < nitems(rt5592_def_bbp); i++) {
+ run_bbp_write(sc, rt5592_def_bbp[i].reg,
+ rt5592_def_bbp[i].val);
+ }
+ for (i = 0; i < nitems(rt5592_bbp_r196); i++) {
+ run_bbp_write(sc, 195, i + 0x80);
+ run_bbp_write(sc, 196, rt5592_bbp_r196[i]);
+ }
+ } else {
+ for (i = 0; i < nitems(rt5390_def_bbp); i++) {
+ run_bbp_write(sc, rt5390_def_bbp[i].reg,
+ rt5390_def_bbp[i].val);
+ }
+ }
+ if (sc->mac_ver == 0x5392) {
+ run_bbp_write(sc, 88, 0x90);
+ run_bbp_write(sc, 95, 0x9a);
+ run_bbp_write(sc, 98, 0x12);
+ run_bbp_write(sc, 106, 0x12);
+ run_bbp_write(sc, 134, 0xd0);
+ run_bbp_write(sc, 135, 0xf6);
+ run_bbp_write(sc, 148, 0x84);
+ }
+
+ run_bbp_read(sc, 152, &bbp);
+ run_bbp_write(sc, 152, bbp | 0x80);
+
+ /* Fix BBP254 for RT5592C. */
+ if (sc->mac_ver == 0x5592 && sc->mac_rev >= 0x0221) {
+ run_bbp_read(sc, 254, &bbp);
+ run_bbp_write(sc, 254, bbp | 0x80);
+ }
+
+ /* Disable hardware antenna diversity. */
+ if (sc->mac_ver == 0x5390)
+ run_bbp_write(sc, 154, 0);
+
+ /* Initialize Rx CCK/OFDM frequency offset report. */
+ run_bbp_write(sc, 142, 1);
+ run_bbp_write(sc, 143, 57);
+}
+
static int
run_bbp_init(struct run_softc *sc)
{
@@ -4337,16 +4840,20 @@ run_bbp_init(struct run_softc *sc)
return (ETIMEDOUT);
/* initialize BBP registers to default values */
- for (i = 0; i < N(rt2860_def_bbp); i++) {
- run_bbp_write(sc, rt2860_def_bbp[i].reg,
- rt2860_def_bbp[i].val);
+ if (sc->mac_ver >= 0x5390)
+ run_rt5390_bbp_init(sc);
+ else {
+ for (i = 0; i < nitems(rt2860_def_bbp); i++) {
+ run_bbp_write(sc, rt2860_def_bbp[i].reg,
+ rt2860_def_bbp[i].val);
+ }
}
/* fix BBP84 for RT2860E */
if (sc->mac_ver == 0x2860 && sc->mac_rev != 0x0101)
run_bbp_write(sc, 84, 0x19);
- if (sc->mac_ver >= 0x3070) {
+ if (sc->mac_ver >= 0x3070 && sc->mac_ver != 0x5592) {
run_bbp_write(sc, 79, 0x13);
run_bbp_write(sc, 80, 0x05);
run_bbp_write(sc, 81, 0x33);
@@ -4361,7 +4868,7 @@ static int
run_rt3070_rf_init(struct run_softc *sc)
{
uint32_t tmp;
- uint8_t rf, target, bbp4;
+ uint8_t bbp4, mingain, rf, target;
int i;
run_rt3070_rf_read(sc, 30, &rf);
@@ -4372,19 +4879,23 @@ run_rt3070_rf_init(struct run_softc *sc)
/* initialize RF registers to default value */
if (sc->mac_ver == 0x3572) {
- for (i = 0; i < N(rt3572_def_rf); i++) {
+ for (i = 0; i < nitems(rt3572_def_rf); i++) {
run_rt3070_rf_write(sc, rt3572_def_rf[i].reg,
rt3572_def_rf[i].val);
}
} else {
- for (i = 0; i < N(rt3070_def_rf); i++) {
+ for (i = 0; i < nitems(rt3070_def_rf); i++) {
run_rt3070_rf_write(sc, rt3070_def_rf[i].reg,
rt3070_def_rf[i].val);
}
}
- if (sc->mac_ver == 0x3070) {
- /* change voltage from 1.2V to 1.35V for RT3070 */
+ if (sc->mac_ver == 0x3070 && sc->mac_rev < 0x0201) {
+ /*
+ * Change voltage from 1.2V to 1.35V for RT3070.
+ * The DAC issue (RT3070_LDO_CFG0) has been fixed
+ * in RT3070(F).
+ */
run_read(sc, RT3070_LDO_CFG0, &tmp);
tmp = (tmp & ~0x0f000000) | 0x0d000000;
run_write(sc, RT3070_LDO_CFG0, tmp);
@@ -4434,7 +4945,7 @@ run_rt3070_rf_init(struct run_softc *sc)
/* select 40MHz bandwidth */
run_bbp_read(sc, 4, &bbp4);
- run_bbp_write(sc, 4, (bbp4 & ~0x08) | 0x10);
+ run_bbp_write(sc, 4, (bbp4 & ~0x18) | 0x10);
run_rt3070_rf_read(sc, 31, &rf);
run_rt3070_rf_write(sc, 31, rf | 0x20);
@@ -4451,7 +4962,7 @@ run_rt3070_rf_init(struct run_softc *sc)
/* save default BBP registers 25 and 26 values */
run_bbp_read(sc, 25, &sc->bbp25);
run_bbp_read(sc, 26, &sc->bbp26);
- } else if (sc->mac_rev < 0x0211)
+ } else if (sc->mac_rev < 0x0201 || sc->mac_rev < 0x0211)
run_rt3070_rf_write(sc, 27, 0x03);
run_read(sc, RT3070_OPT_14, &tmp);
@@ -4464,7 +4975,8 @@ run_rt3070_rf_init(struct run_softc *sc)
(sc->mac_ver == 0x3071 && sc->mac_rev >= 0x0211)) &&
!sc->ext_2ghz_lna)
rf |= 0x20; /* fix for long range Rx issue */
- if (sc->txmixgain_2ghz >= 1)
+ mingain = (sc->mac_ver == 0x3070) ? 1 : 2;
+ if (sc->txmixgain_2ghz >= mingain)
rf = (rf & ~0x7) | sc->txmixgain_2ghz;
run_rt3070_rf_write(sc, 17, rf);
}
@@ -4496,6 +5008,70 @@ run_rt3070_rf_init(struct run_softc *sc)
return (0);
}
+static void
+run_rt5390_rf_init(struct run_softc *sc)
+{
+ uint32_t tmp;
+ uint8_t rf;
+ int i;
+
+ /* Toggle RF R2 to initiate calibration. */
+ if (sc->mac_ver == 0x5390) {
+ run_rt3070_rf_read(sc, 2, &rf);
+ run_rt3070_rf_write(sc, 2, rf | RT5390_RESCAL);
+ run_delay(sc, 10);
+ run_rt3070_rf_write(sc, 2, rf & ~RT5390_RESCAL);
+ } else {
+ run_rt3070_rf_write(sc, 2, RT5390_RESCAL);
+ run_delay(sc, 10);
+ }
+
+ /* Initialize RF registers to default value. */
+ if (sc->mac_ver == 0x5592) {
+ for (i = 0; i < nitems(rt5592_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt5592_def_rf[i].reg,
+ rt5592_def_rf[i].val);
+ }
+ /* Initialize RF frequency offset. */
+ run_adjust_freq_offset(sc);
+ } else if (sc->mac_ver == 0x5392) {
+ for (i = 0; i < nitems(rt5392_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt5392_def_rf[i].reg,
+ rt5392_def_rf[i].val);
+ }
+ if (sc->mac_rev >= 0x0223) {
+ run_rt3070_rf_write(sc, 23, 0x0f);
+ run_rt3070_rf_write(sc, 24, 0x3e);
+ run_rt3070_rf_write(sc, 51, 0x32);
+ run_rt3070_rf_write(sc, 53, 0x22);
+ run_rt3070_rf_write(sc, 56, 0xc1);
+ run_rt3070_rf_write(sc, 59, 0x0f);
+ }
+ } else {
+ for (i = 0; i < nitems(rt5390_def_rf); i++) {
+ run_rt3070_rf_write(sc, rt5390_def_rf[i].reg,
+ rt5390_def_rf[i].val);
+ }
+ if (sc->mac_rev >= 0x0502) {
+ run_rt3070_rf_write(sc, 6, 0xe0);
+ run_rt3070_rf_write(sc, 25, 0x80);
+ run_rt3070_rf_write(sc, 46, 0x73);
+ run_rt3070_rf_write(sc, 53, 0x00);
+ run_rt3070_rf_write(sc, 56, 0x42);
+ run_rt3070_rf_write(sc, 61, 0xd1);
+ }
+ }
+
+ sc->rf24_20mhz = 0x1f; /* default value */
+ sc->rf24_40mhz = (sc->mac_ver == 0x5592) ? 0 : 0x2f;
+
+ if (sc->mac_rev < 0x0211)
+ run_rt3070_rf_write(sc, 27, 0x3);
+
+ run_read(sc, RT3070_OPT_14, &tmp);
+ run_write(sc, RT3070_OPT_14, tmp | 1);
+}
+
static int
run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target,
uint8_t *val)
@@ -4525,7 +5101,7 @@ run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target,
break;
}
if (ntries == 100)
- return ETIMEDOUT;
+ return (ETIMEDOUT);
/* set power and frequency of stopband test tone */
run_bbp_write(sc, 24, 0x06);
@@ -4567,7 +5143,49 @@ run_rt3070_rf_setup(struct run_softc *sc)
uint8_t bbp, rf;
int i;
- if (sc->mac_ver == 0x3572) {
+ if (sc->mac_ver >= 0x5390) {
+ if (sc->mac_rev >= 0x0211) {
+ /* Enable DC filter. */
+ run_bbp_write(sc, 103, 0xc0);
+
+ if (sc->mac_ver != 0x5592) {
+ /* Improve power consumption. */
+ run_bbp_read(sc, 31, &bbp);
+ run_bbp_write(sc, 31, bbp & ~0x03);
+ }
+ }
+
+ run_bbp_read(sc, 138, &bbp);
+ if (sc->ntxchains == 1)
+ bbp |= 0x20; /* turn off DAC1 */
+ if (sc->nrxchains == 1)
+ bbp &= ~0x02; /* turn off ADC1 */
+ run_bbp_write(sc, 138, bbp);
+
+ run_rt3070_rf_read(sc, 38, &rf);
+ run_rt3070_rf_write(sc, 38, rf & ~RT5390_RX_LO1);
+
+ run_rt3070_rf_read(sc, 39, &rf);
+ run_rt3070_rf_write(sc, 39, rf & ~RT5390_RX_LO2);
+
+ /* Avoid data lost and CRC error. */
+ run_bbp_read(sc, 4, &bbp);
+ run_bbp_write(sc, 4, bbp | RT5390_MAC_IF_CTRL);
+
+ run_rt3070_rf_read(sc, 30, &rf);
+ rf = (rf & ~0x18) | 0x10;
+ run_rt3070_rf_write(sc, 30, rf);
+
+ if (sc->mac_ver != 0x5592) {
+ run_write(sc, RT2860_TX_SW_CFG1, 0);
+ if (sc->mac_rev < 0x0211) {
+ run_write(sc, RT2860_TX_SW_CFG2,
+ sc->patch_dac ? 0x2c : 0x0f);
+ } else
+ run_write(sc, RT2860_TX_SW_CFG2, 0);
+ }
+
+ } else if (sc->mac_ver == 0x3572) {
/* enable DC filter */
if (sc->mac_rev >= 0x0201)
run_bbp_write(sc, 103, 0xc0);
@@ -4590,10 +5208,15 @@ run_rt3070_rf_setup(struct run_softc *sc)
run_rt3070_rf_write(sc, 16, rf);
} else if (sc->mac_ver == 0x3071) {
- /* enable DC filter */
- if (sc->mac_rev >= 0x0201)
+ if (sc->mac_rev >= 0x0211) {
+ /* enable DC filter */
run_bbp_write(sc, 103, 0xc0);
+ /* improve power consumption */
+ run_bbp_read(sc, 31, &bbp);
+ run_bbp_write(sc, 31, bbp & ~0x03);
+ }
+
run_bbp_read(sc, 138, &bbp);
if (sc->ntxchains == 1)
bbp |= 0x20; /* turn off DAC1 */
@@ -4601,12 +5224,6 @@ run_rt3070_rf_setup(struct run_softc *sc)
bbp &= ~0x02; /* turn off ADC1 */
run_bbp_write(sc, 138, bbp);
- if (sc->mac_rev >= 0x0211) {
- /* improve power consumption */
- run_bbp_read(sc, 31, &bbp);
- run_bbp_write(sc, 31, bbp & ~0x03);
- }
-
run_write(sc, RT2860_TX_SW_CFG1, 0);
if (sc->mac_rev < 0x0211) {
run_write(sc, RT2860_TX_SW_CFG2,
@@ -4624,7 +5241,7 @@ run_rt3070_rf_setup(struct run_softc *sc)
run_bbp_write(sc, 31, bbp & ~0x03);
}
- if (sc->mac_rev < 0x0211) {
+ if (sc->mac_rev < 0x0201) {
run_write(sc, RT2860_TX_SW_CFG1, 0);
run_write(sc, RT2860_TX_SW_CFG2, 0x2c);
} else
@@ -4632,7 +5249,7 @@ run_rt3070_rf_setup(struct run_softc *sc)
}
/* initialize RF registers from ROM for >=RT3071*/
- if (sc->mac_ver >= 0x3071) {
+ if (sc->mac_ver >= 0x3071 && sc->mac_ver < 0x5390) {
for (i = 0; i < 10; i++) {
if (sc->rf[i].reg == 0 || sc->rf[i].reg == 0xff)
continue;
@@ -4651,13 +5268,13 @@ run_txrx_enable(struct run_softc *sc)
run_write(sc, RT2860_MAC_SYS_CTRL, RT2860_MAC_TX_EN);
for (ntries = 0; ntries < 200; ntries++) {
if ((error = run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp)) != 0)
- return error;
+ return (error);
if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0)
break;
run_delay(sc, 50);
}
if (ntries == 200)
- return ETIMEDOUT;
+ return (ETIMEDOUT);
run_delay(sc, 50);
@@ -4688,6 +5305,20 @@ run_txrx_enable(struct run_softc *sc)
}
static void
+run_adjust_freq_offset(struct run_softc *sc)
+{
+ uint8_t rf, tmp;
+
+ run_rt3070_rf_read(sc, 17, &rf);
+ tmp = rf;
+ rf = (rf & ~0x7f) | (sc->freq & 0x7f);
+ rf = MIN(rf, 0x5f);
+
+ if (tmp != rf)
+ run_mcu_cmd(sc, 0x74, (tmp << 8 ) | rf);
+}
+
+static void
run_init_locked(struct run_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
@@ -4760,13 +5391,26 @@ run_init_locked(struct run_softc *sc)
run_write(sc, RT2860_TX_PWR_CFG(ridx), sc->txpow20mhz[ridx]);
}
- for (i = 0; i < N(rt2870_def_mac); i++)
+ for (i = 0; i < nitems(rt2870_def_mac); i++)
run_write(sc, rt2870_def_mac[i].reg, rt2870_def_mac[i].val);
run_write(sc, RT2860_WMM_AIFSN_CFG, 0x00002273);
run_write(sc, RT2860_WMM_CWMIN_CFG, 0x00002344);
run_write(sc, RT2860_WMM_CWMAX_CFG, 0x000034aa);
- if (sc->mac_ver >= 0x3070) {
+ if (sc->mac_ver >= 0x5390) {
+ run_write(sc, RT2860_TX_SW_CFG0,
+ 4 << RT2860_DLY_PAPE_EN_SHIFT | 4);
+ if (sc->mac_ver >= 0x5392) {
+ run_write(sc, RT2860_MAX_LEN_CFG, 0x00002fff);
+ if (sc->mac_ver == 0x5592) {
+ run_write(sc, RT2860_HT_FBK_CFG1, 0xedcba980);
+ run_write(sc, RT2860_TXOP_HLDR_ET, 0x00000082);
+ } else {
+ run_write(sc, RT2860_HT_FBK_CFG1, 0xedcb4980);
+ run_write(sc, RT2860_LG_FBK_CFG0, 0xedcba322);
+ }
+ }
+ } else if (sc->mac_ver >= 0x3070) {
/* set delay of PA_PE assertion to 1us (unit of 0.25us) */
run_write(sc, RT2860_TX_SW_CFG0,
4 << RT2860_DLY_PAPE_EN_SHIFT);
@@ -4823,14 +5467,16 @@ run_init_locked(struct run_softc *sc)
run_write(sc, RT2860_WMM_TXOP1_CFG, 48 << 16 | 96);
/* write vendor-specific BBP values (from EEPROM) */
- for (i = 0; i < 10; i++) {
- if (sc->bbp[i].reg == 0 || sc->bbp[i].reg == 0xff)
- continue;
- run_bbp_write(sc, sc->bbp[i].reg, sc->bbp[i].val);
+ if (sc->mac_ver < 0x5390) {
+ for (i = 0; i < 10; i++) {
+ if (sc->bbp[i].reg == 0 || sc->bbp[i].reg == 0xff)
+ continue;
+ run_bbp_write(sc, sc->bbp[i].reg, sc->bbp[i].val);
+ }
}
/* select Main antenna for 1T1R devices */
- if (sc->rf_rev == RT3070_RF_3020)
+ if (sc->rf_rev == RT3070_RF_3020 || sc->rf_rev == RT5390_RF_5370)
run_set_rx_antenna(sc, 0);
/* send LEDs operating mode to microcontroller */
@@ -4838,7 +5484,9 @@ run_init_locked(struct run_softc *sc)
(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1]);
(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2]);
- if (sc->mac_ver >= 0x3070)
+ if (sc->mac_ver >= 0x5390)
+ run_rt5390_rf_init(sc);
+ else if (sc->mac_ver >= 0x3070)
run_rt3070_rf_init(sc);
/* disable non-existing Rx chains */
@@ -4932,6 +5580,24 @@ run_stop(void *arg)
sc->rx_m = NULL;
}
+ /* Disable Tx/Rx DMA. */
+ if (run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp) != 0)
+ return;
+ tmp &= ~(RT2860_RX_DMA_EN | RT2860_TX_DMA_EN);
+ run_write(sc, RT2860_WPDMA_GLO_CFG, tmp);
+
+ for (ntries = 0; ntries < 100; ntries++) {
+ if (run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp) != 0)
+ return;
+ if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0)
+ break;
+ run_delay(sc, 10);
+ }
+ if (ntries == 100) {
+ device_printf(sc->sc_dev, "timeout waiting for DMA engine\n");
+ return;
+ }
+
/* disable Tx/Rx */
run_read(sc, RT2860_MAC_SYS_CTRL, &tmp);
tmp &= ~(RT2860_MAC_RX_EN | RT2860_MAC_TX_EN);
@@ -4959,12 +5625,10 @@ run_stop(void *arg)
for (i = 0; i != RUN_EP_QUEUES; i++)
run_unsetup_tx_list(sc, &sc->sc_epq[i]);
-
- return;
}
static void
-run_delay(struct run_softc *sc, unsigned int ms)
+run_delay(struct run_softc *sc, u_int ms)
{
usb_pause_mtx(mtx_owned(&sc->sc_mtx) ?
&sc->sc_mtx : NULL, USB_MS_TO_TICKS(ms));
@@ -4986,7 +5650,7 @@ static driver_t run_driver = {
static devclass_t run_devclass;
-DRIVER_MODULE(run, uhub, run_driver, run_devclass, NULL, 0);
+DRIVER_MODULE(run, uhub, run_driver, run_devclass, NULL, NULL);
MODULE_DEPEND(run, wlan, 1, 1, 1);
MODULE_DEPEND(run, usb, 1, 1, 1);
MODULE_DEPEND(run, firmware, 1, 1, 1);
diff --git a/sys/dev/usb/wlan/if_runreg.h b/sys/dev/usb/wlan/if_runreg.h
index 3a5125f..4bd6b45 100644
--- a/sys/dev/usb/wlan/if_runreg.h
+++ b/sys/dev/usb/wlan/if_runreg.h
@@ -22,13 +22,6 @@
#ifndef _IF_RUNREG_H_
#define _IF_RUNREG_H_
-/* PCI registers */
-#define RT2860_PCI_CFG 0x0000
-#define RT2860_PCI_EECTRL 0x0004
-#define RT2860_PCI_MCUCTRL 0x0008
-#define RT2860_PCI_SYSCTRL 0x000c
-#define RT2860_PCIE_JTAG 0x0010
-
#define RT2860_CONFIG_NO 1
#define RT2860_IFACE_INDEX 0
@@ -85,6 +78,9 @@
#define RT3070_LDO_CFG0 0x05d4
#define RT3070_GPIO_SWITCH 0x05dc
+/* RT5592 registers */
+#define RT5592_DEBUG_INDEX 0x05e8
+
/* MAC registers */
#define RT2860_ASIC_VER_ID 0x1000
#define RT2860_MAC_SYS_CTRL 0x1004
@@ -209,6 +205,7 @@
#define RT2860_H2M_MAILBOX 0x7010
#define RT2860_H2M_MAILBOX_CID 0x7014
#define RT2860_H2M_MAILBOX_STATUS 0x701c
+#define RT2860_H2M_INTSRC 0x7024
#define RT2860_H2M_BBPAGENT 0x7028
#define RT2860_BCN_BASE(vap) (0x7800 + (vap) * 512)
@@ -386,6 +383,9 @@
#define RT3070_EFSROM_MODE_MASK 0x000000c0
#define RT3070_EFUSE_AOUT_MASK 0x0000003f
+/* possible flag for register DEBUG_INDEX */
+#define RT5592_SEL_XTAL (1U << 31)
+
/* possible flags for register MAC_SYS_CTRL */
#define RT2860_RX_TS_EN (1 << 7)
#define RT2860_WLAN_HALT_EN (1 << 6)
@@ -688,6 +688,7 @@
/* possible flags for RT3020 RF register 1 */
#define RT3070_RF_BLOCK (1 << 0)
+#define RT3070_PLL_PD (1 << 1)
#define RT3070_RX0_PD (1 << 2)
#define RT3070_TX0_PD (1 << 3)
#define RT3070_RX1_PD (1 << 4)
@@ -705,6 +706,24 @@
/* possible flags for RT3020 RF register 21 */
#define RT3070_RX_LO2 (1 << 3)
+/* Possible flags for RT5390 RF register 2. */
+#define RT5390_RESCAL (1 << 7)
+
+/* Possible flags for RT5390 RF register 3. */
+#define RT5390_VCOCAL (1 << 7)
+
+/* Possible flags for RT5390 RF register 38. */
+#define RT5390_RX_LO1 (1 << 5)
+
+/* Possible flags for RT5390 RF register 39. */
+#define RT5390_RX_LO2 (1 << 7)
+
+/* Possible flags for RT5390 BBP register 4. */
+#define RT5390_MAC_IF_CTRL (1 << 6)
+
+/* Possible flags for RT5390 BBP register 105. */
+#define RT5390_MLD (1 << 2)
+#define RT5390_EN_SIG_MODULATION (1 << 3)
/* RT2860 TX descriptor */
struct rt2860_txd {
@@ -827,27 +846,18 @@ struct rt2860_rxwi {
uint16_t reserved2;
} __packed;
-
-/* first DMA segment contains TXWI + 802.11 header + 32-bit padding */
-#define RT2860_TXWI_DMASZ \
- (sizeof (struct rt2860_txwi) + \
- sizeof (struct ieee80211_htframe) + \
- sizeof (uint16_t))
-
-#define RT2860_RF1 0
-#define RT2860_RF2 2
-#define RT2860_RF3 1
-#define RT2860_RF4 3
-
-#define RT2860_RF_2820 1 /* 2T3R */
-#define RT2860_RF_2850 2 /* dual-band 2T3R */
-#define RT2860_RF_2720 3 /* 1T2R */
-#define RT2860_RF_2750 4 /* dual-band 1T2R */
-#define RT3070_RF_3020 5 /* 1T1R */
-#define RT3070_RF_2020 6 /* b/g */
-#define RT3070_RF_3021 7 /* 1T2R */
-#define RT3070_RF_3022 8 /* 2T2R */
-#define RT3070_RF_3052 9 /* dual-band 2T2R */
+#define RT2860_RF_2820 0x0001 /* 2T3R */
+#define RT2860_RF_2850 0x0002 /* dual-band 2T3R */
+#define RT2860_RF_2720 0x0003 /* 1T2R */
+#define RT2860_RF_2750 0x0004 /* dual-band 1T2R */
+#define RT3070_RF_3020 0x0005 /* 1T1R */
+#define RT3070_RF_2020 0x0006 /* b/g */
+#define RT3070_RF_3021 0x0007 /* 1T2R */
+#define RT3070_RF_3022 0x0008 /* 2T2R */
+#define RT3070_RF_3052 0x0009 /* dual-band 2T2R */
+#define RT5592_RF_5592 0x000f /* dual-band 2T2R */
+#define RT5390_RF_5370 0x5370 /* 1T1R */
+#define RT5390_RF_5372 0x5372 /* 2T2R */
/* USB commands for RT2870 only */
#define RT2870_RESET 1
@@ -1041,63 +1051,126 @@ static const struct rt2860_rate {
{ 105, 0x05 }, \
{ 106, 0x35 }
+#define RT5390_DEF_BBP \
+ { 31, 0x08 }, \
+ { 65, 0x2c }, \
+ { 66, 0x38 }, \
+ { 68, 0x0b }, \
+ { 69, 0x0d }, \
+ { 70, 0x06 }, \
+ { 73, 0x13 }, \
+ { 75, 0x46 }, \
+ { 76, 0x28 }, \
+ { 77, 0x59 }, \
+ { 81, 0x37 }, \
+ { 82, 0x62 }, \
+ { 83, 0x7a }, \
+ { 84, 0x9a }, \
+ { 86, 0x38 }, \
+ { 91, 0x04 }, \
+ { 92, 0x02 }, \
+ { 103, 0xc0 }, \
+ { 104, 0x92 }, \
+ { 105, 0x3c }, \
+ { 106, 0x03 }, \
+ { 128, 0x12 }
+
+#define RT5592_DEF_BBP \
+ { 20, 0x06 }, \
+ { 31, 0x08 }, \
+ { 65, 0x2c }, \
+ { 66, 0x38 }, \
+ { 68, 0xdd }, \
+ { 69, 0x1a }, \
+ { 70, 0x05 }, \
+ { 73, 0x13 }, \
+ { 74, 0x0f }, \
+ { 75, 0x4f }, \
+ { 76, 0x28 }, \
+ { 77, 0x59 }, \
+ { 81, 0x37 }, \
+ { 82, 0x62 }, \
+ { 83, 0x6a }, \
+ { 84, 0x9a }, \
+ { 86, 0x38 }, \
+ { 88, 0x90 }, \
+ { 91, 0x04 }, \
+ { 92, 0x02 }, \
+ { 95, 0x9a }, \
+ { 98, 0x12 }, \
+ { 103, 0xc0 }, \
+ { 104, 0x92 }, \
+ { 105, 0x3c }, \
+ { 106, 0x35 }, \
+ { 128, 0x12 }, \
+ { 134, 0xd0 }, \
+ { 135, 0xf6 }, \
+ { 137, 0x0f }
+
/*
* Default settings for RF registers; values derived from the reference driver.
*/
-#define RT2860_RF2850 \
- { 1, 0x100bb3, 0x1301e1, 0x05a014, 0x001402 }, \
- { 2, 0x100bb3, 0x1301e1, 0x05a014, 0x001407 }, \
- { 3, 0x100bb3, 0x1301e2, 0x05a014, 0x001402 }, \
- { 4, 0x100bb3, 0x1301e2, 0x05a014, 0x001407 }, \
- { 5, 0x100bb3, 0x1301e3, 0x05a014, 0x001402 }, \
- { 6, 0x100bb3, 0x1301e3, 0x05a014, 0x001407 }, \
- { 7, 0x100bb3, 0x1301e4, 0x05a014, 0x001402 }, \
- { 8, 0x100bb3, 0x1301e4, 0x05a014, 0x001407 }, \
- { 9, 0x100bb3, 0x1301e5, 0x05a014, 0x001402 }, \
- { 10, 0x100bb3, 0x1301e5, 0x05a014, 0x001407 }, \
- { 11, 0x100bb3, 0x1301e6, 0x05a014, 0x001402 }, \
- { 12, 0x100bb3, 0x1301e6, 0x05a014, 0x001407 }, \
- { 13, 0x100bb3, 0x1301e7, 0x05a014, 0x001402 }, \
- { 14, 0x100bb3, 0x1301e8, 0x05a014, 0x001404 }, \
- { 36, 0x100bb3, 0x130266, 0x056014, 0x001408 }, \
- { 38, 0x100bb3, 0x130267, 0x056014, 0x001404 }, \
- { 40, 0x100bb2, 0x1301a0, 0x056014, 0x001400 }, \
- { 44, 0x100bb2, 0x1301a0, 0x056014, 0x001408 }, \
- { 46, 0x100bb2, 0x1301a1, 0x056014, 0x001402 }, \
- { 48, 0x100bb2, 0x1301a1, 0x056014, 0x001406 }, \
- { 52, 0x100bb2, 0x1301a2, 0x056014, 0x001404 }, \
- { 54, 0x100bb2, 0x1301a2, 0x056014, 0x001408 }, \
- { 56, 0x100bb2, 0x1301a3, 0x056014, 0x001402 }, \
- { 60, 0x100bb2, 0x1301a4, 0x056014, 0x001400 }, \
- { 62, 0x100bb2, 0x1301a4, 0x056014, 0x001404 }, \
- { 64, 0x100bb2, 0x1301a4, 0x056014, 0x001408 }, \
- { 100, 0x100bb2, 0x1301ac, 0x05e014, 0x001400 }, \
- { 102, 0x100bb2, 0x1701ac, 0x15e014, 0x001404 }, \
- { 104, 0x100bb2, 0x1701ac, 0x15e014, 0x001408 }, \
- { 108, 0x100bb3, 0x17028c, 0x15e014, 0x001404 }, \
- { 110, 0x100bb3, 0x13028d, 0x05e014, 0x001400 }, \
- { 112, 0x100bb3, 0x13028d, 0x05e014, 0x001406 }, \
- { 116, 0x100bb3, 0x13028e, 0x05e014, 0x001408 }, \
- { 118, 0x100bb3, 0x13028f, 0x05e014, 0x001404 }, \
- { 120, 0x100bb1, 0x1300e0, 0x05e014, 0x001400 }, \
- { 124, 0x100bb1, 0x1300e0, 0x05e014, 0x001404 }, \
- { 126, 0x100bb1, 0x1300e0, 0x05e014, 0x001406 }, \
- { 128, 0x100bb1, 0x1300e0, 0x05e014, 0x001408 }, \
- { 132, 0x100bb1, 0x1300e1, 0x05e014, 0x001402 }, \
- { 134, 0x100bb1, 0x1300e1, 0x05e014, 0x001404 }, \
- { 136, 0x100bb1, 0x1300e1, 0x05e014, 0x001406 }, \
- { 140, 0x100bb1, 0x1300e2, 0x05e014, 0x001400 }, \
- { 149, 0x100bb1, 0x1300e2, 0x05e014, 0x001409 }, \
- { 151, 0x100bb1, 0x1300e3, 0x05e014, 0x001401 }, \
- { 153, 0x100bb1, 0x1300e3, 0x05e014, 0x001403 }, \
- { 157, 0x100bb1, 0x1300e3, 0x05e014, 0x001407 }, \
- { 159, 0x100bb1, 0x1300e3, 0x05e014, 0x001409 }, \
- { 161, 0x100bb1, 0x1300e4, 0x05e014, 0x001401 }, \
- { 165, 0x100bb1, 0x1300e4, 0x05e014, 0x001405 }, \
- { 167, 0x100bb1, 0x1300f4, 0x05e014, 0x001407 }, \
- { 169, 0x100bb1, 0x1300f4, 0x05e014, 0x001409 }, \
- { 171, 0x100bb1, 0x1300f5, 0x05e014, 0x001401 }, \
- { 173, 0x100bb1, 0x1300f5, 0x05e014, 0x001403 }
+#define RT2860_RF2850 \
+ { 1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b }, \
+ { 2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f }, \
+ { 3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b }, \
+ { 4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f }, \
+ { 5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b }, \
+ { 6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f }, \
+ { 7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b }, \
+ { 8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f }, \
+ { 9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b }, \
+ { 10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f }, \
+ { 11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b }, \
+ { 12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f }, \
+ { 13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b }, \
+ { 14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193 }, \
+ { 36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3 }, \
+ { 38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193 }, \
+ { 40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183 }, \
+ { 44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3 }, \
+ { 46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b }, \
+ { 48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b }, \
+ { 52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193 }, \
+ { 54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3 }, \
+ { 56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b }, \
+ { 60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183 }, \
+ { 62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193 }, \
+ { 64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3 }, \
+ { 100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783 }, \
+ { 102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793 }, \
+ { 104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3 }, \
+ { 108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193 }, \
+ { 110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183 }, \
+ { 112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b }, \
+ { 116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3 }, \
+ { 118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193 }, \
+ { 120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183 }, \
+ { 124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193 }, \
+ { 126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b }, \
+ { 128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3 }, \
+ { 132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b }, \
+ { 134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193 }, \
+ { 136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b }, \
+ { 140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183 }, \
+ { 149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7 }, \
+ { 151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187 }, \
+ { 153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f }, \
+ { 157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f }, \
+ { 159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7 }, \
+ { 161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187 }, \
+ { 165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197 }, \
+ { 167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f }, \
+ { 169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327 }, \
+ { 171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307 }, \
+ { 173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f }, \
+ { 184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b }, \
+ { 188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13 }, \
+ { 192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b }, \
+ { 196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23 }, \
+ { 208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13 }, \
+ { 212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b }, \
+ { 216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23 }
#define RT3070_RF3052 \
{ 0xf1, 2, 2 }, \
@@ -1154,6 +1227,116 @@ static const struct rt2860_rate {
{ 0x61, 0, 7 }, \
{ 0x61, 0, 9 }
+#define RT5592_RF5592_20MHZ \
+ { 0x1e2, 4, 10, 3 }, \
+ { 0x1e3, 4, 10, 3 }, \
+ { 0x1e4, 4, 10, 3 }, \
+ { 0x1e5, 4, 10, 3 }, \
+ { 0x1e6, 4, 10, 3 }, \
+ { 0x1e7, 4, 10, 3 }, \
+ { 0x1e8, 4, 10, 3 }, \
+ { 0x1e9, 4, 10, 3 }, \
+ { 0x1ea, 4, 10, 3 }, \
+ { 0x1eb, 4, 10, 3 }, \
+ { 0x1ec, 4, 10, 3 }, \
+ { 0x1ed, 4, 10, 3 }, \
+ { 0x1ee, 4, 10, 3 }, \
+ { 0x1f0, 8, 10, 3 }, \
+ { 0xac, 8, 12, 1 }, \
+ { 0xad, 0, 12, 1 }, \
+ { 0xad, 4, 12, 1 }, \
+ { 0xae, 0, 12, 1 }, \
+ { 0xae, 4, 12, 1 }, \
+ { 0xae, 8, 12, 1 }, \
+ { 0xaf, 4, 12, 1 }, \
+ { 0xaf, 8, 12, 1 }, \
+ { 0xb0, 0, 12, 1 }, \
+ { 0xb0, 8, 12, 1 }, \
+ { 0xb1, 0, 12, 1 }, \
+ { 0xb1, 4, 12, 1 }, \
+ { 0xb7, 4, 12, 1 }, \
+ { 0xb7, 8, 12, 1 }, \
+ { 0xb8, 0, 12, 1 }, \
+ { 0xb8, 8, 12, 1 }, \
+ { 0xb9, 0, 12, 1 }, \
+ { 0xb9, 4, 12, 1 }, \
+ { 0xba, 0, 12, 1 }, \
+ { 0xba, 4, 12, 1 }, \
+ { 0xba, 8, 12, 1 }, \
+ { 0xbb, 4, 12, 1 }, \
+ { 0xbb, 8, 12, 1 }, \
+ { 0xbc, 0, 12, 1 }, \
+ { 0xbc, 8, 12, 1 }, \
+ { 0xbd, 0, 12, 1 }, \
+ { 0xbd, 4, 12, 1 }, \
+ { 0xbe, 0, 12, 1 }, \
+ { 0xbf, 6, 12, 1 }, \
+ { 0xbf, 10, 12, 1 }, \
+ { 0xc0, 2, 12, 1 }, \
+ { 0xc0, 10, 12, 1 }, \
+ { 0xc1, 2, 12, 1 }, \
+ { 0xc1, 6, 12, 1 }, \
+ { 0xc2, 2, 12, 1 }, \
+ { 0xa4, 0, 12, 1 }, \
+ { 0xa4, 4, 12, 1 }, \
+ { 0xa5, 8, 12, 1 }, \
+ { 0xa6, 0, 12, 1 }
+
+#define RT5592_RF5592_40MHZ \
+ { 0xf1, 2, 10, 3 }, \
+ { 0xf1, 7, 10, 3 }, \
+ { 0xf2, 2, 10, 3 }, \
+ { 0xf2, 7, 10, 3 }, \
+ { 0xf3, 2, 10, 3 }, \
+ { 0xf3, 7, 10, 3 }, \
+ { 0xf4, 2, 10, 3 }, \
+ { 0xf4, 7, 10, 3 }, \
+ { 0xf5, 2, 10, 3 }, \
+ { 0xf5, 7, 10, 3 }, \
+ { 0xf6, 2, 10, 3 }, \
+ { 0xf6, 7, 10, 3 }, \
+ { 0xf7, 2, 10, 3 }, \
+ { 0xf8, 4, 10, 3 }, \
+ { 0x56, 4, 12, 1 }, \
+ { 0x56, 6, 12, 1 }, \
+ { 0x56, 8, 12, 1 }, \
+ { 0x57, 0, 12, 1 }, \
+ { 0x57, 2, 12, 1 }, \
+ { 0x57, 4, 12, 1 }, \
+ { 0x57, 8, 12, 1 }, \
+ { 0x57, 10, 12, 1 }, \
+ { 0x58, 0, 12, 1 }, \
+ { 0x58, 4, 12, 1 }, \
+ { 0x58, 6, 12, 1 }, \
+ { 0x58, 8, 12, 1 }, \
+ { 0x5b, 8, 12, 1 }, \
+ { 0x5b, 10, 12, 1 }, \
+ { 0x5c, 0, 12, 1 }, \
+ { 0x5c, 4, 12, 1 }, \
+ { 0x5c, 6, 12, 1 }, \
+ { 0x5c, 8, 12, 1 }, \
+ { 0x5d, 0, 12, 1 }, \
+ { 0x5d, 2, 12, 1 }, \
+ { 0x5d, 4, 12, 1 }, \
+ { 0x5d, 8, 12, 1 }, \
+ { 0x5d, 10, 12, 1 }, \
+ { 0x5e, 0, 12, 1 }, \
+ { 0x5e, 4, 12, 1 }, \
+ { 0x5e, 6, 12, 1 }, \
+ { 0x5e, 8, 12, 1 }, \
+ { 0x5f, 0, 12, 1 }, \
+ { 0x5f, 9, 12, 1 }, \
+ { 0x5f, 11, 12, 1 }, \
+ { 0x60, 1, 12, 1 }, \
+ { 0x60, 5, 12, 1 }, \
+ { 0x60, 7, 12, 1 }, \
+ { 0x60, 9, 12, 1 }, \
+ { 0x61, 1, 12, 1 }, \
+ { 0x52, 0, 12, 1 }, \
+ { 0x52, 4, 12, 1 }, \
+ { 0x52, 8, 12, 1 }, \
+ { 0x53, 0, 12, 1 }
+
#define RT3070_DEF_RF \
{ 4, 0x40 }, \
{ 5, 0x03 }, \
@@ -1208,6 +1391,246 @@ static const struct rt2860_rate {
{ 30, 0x09 }, \
{ 31, 0x10 }
+#define RT5390_DEF_RF \
+ { 1, 0x0f }, \
+ { 2, 0x80 }, \
+ { 3, 0x88 }, \
+ { 5, 0x10 }, \
+ { 6, 0xa0 }, \
+ { 7, 0x00 }, \
+ { 10, 0x53 }, \
+ { 11, 0x4a }, \
+ { 12, 0x46 }, \
+ { 13, 0x9f }, \
+ { 14, 0x00 }, \
+ { 15, 0x00 }, \
+ { 16, 0x00 }, \
+ { 18, 0x03 }, \
+ { 19, 0x00 }, \
+ { 20, 0x00 }, \
+ { 21, 0x00 }, \
+ { 22, 0x20 }, \
+ { 23, 0x00 }, \
+ { 24, 0x00 }, \
+ { 25, 0xc0 }, \
+ { 26, 0x00 }, \
+ { 27, 0x09 }, \
+ { 28, 0x00 }, \
+ { 29, 0x10 }, \
+ { 30, 0x10 }, \
+ { 31, 0x80 }, \
+ { 32, 0x80 }, \
+ { 33, 0x00 }, \
+ { 34, 0x07 }, \
+ { 35, 0x12 }, \
+ { 36, 0x00 }, \
+ { 37, 0x08 }, \
+ { 38, 0x85 }, \
+ { 39, 0x1b }, \
+ { 40, 0x0b }, \
+ { 41, 0xbb }, \
+ { 42, 0xd2 }, \
+ { 43, 0x9a }, \
+ { 44, 0x0e }, \
+ { 45, 0xa2 }, \
+ { 46, 0x7b }, \
+ { 47, 0x00 }, \
+ { 48, 0x10 }, \
+ { 49, 0x94 }, \
+ { 52, 0x38 }, \
+ { 53, 0x84 }, \
+ { 54, 0x78 }, \
+ { 55, 0x44 }, \
+ { 56, 0x22 }, \
+ { 57, 0x80 }, \
+ { 58, 0x7f }, \
+ { 59, 0x8f }, \
+ { 60, 0x45 }, \
+ { 61, 0xdd }, \
+ { 62, 0x00 }, \
+ { 63, 0x00 }
+
+#define RT5392_DEF_RF \
+ { 1, 0x17 }, \
+ { 3, 0x88 }, \
+ { 5, 0x10 }, \
+ { 6, 0xe0 }, \
+ { 7, 0x00 }, \
+ { 10, 0x53 }, \
+ { 11, 0x4a }, \
+ { 12, 0x46 }, \
+ { 13, 0x9f }, \
+ { 14, 0x00 }, \
+ { 15, 0x00 }, \
+ { 16, 0x00 }, \
+ { 18, 0x03 }, \
+ { 19, 0x4d }, \
+ { 20, 0x00 }, \
+ { 21, 0x8d }, \
+ { 22, 0x20 }, \
+ { 23, 0x0b }, \
+ { 24, 0x44 }, \
+ { 25, 0x80 }, \
+ { 26, 0x82 }, \
+ { 27, 0x09 }, \
+ { 28, 0x00 }, \
+ { 29, 0x10 }, \
+ { 30, 0x10 }, \
+ { 31, 0x80 }, \
+ { 32, 0x20 }, \
+ { 33, 0xc0 }, \
+ { 34, 0x07 }, \
+ { 35, 0x12 }, \
+ { 36, 0x00 }, \
+ { 37, 0x08 }, \
+ { 38, 0x89 }, \
+ { 39, 0x1b }, \
+ { 40, 0x0f }, \
+ { 41, 0xbb }, \
+ { 42, 0xd5 }, \
+ { 43, 0x9b }, \
+ { 44, 0x0e }, \
+ { 45, 0xa2 }, \
+ { 46, 0x73 }, \
+ { 47, 0x0c }, \
+ { 48, 0x10 }, \
+ { 49, 0x94 }, \
+ { 50, 0x94 }, \
+ { 51, 0x3a }, \
+ { 52, 0x48 }, \
+ { 53, 0x44 }, \
+ { 54, 0x38 }, \
+ { 55, 0x43 }, \
+ { 56, 0xa1 }, \
+ { 57, 0x00 }, \
+ { 58, 0x39 }, \
+ { 59, 0x07 }, \
+ { 60, 0x45 }, \
+ { 61, 0x91 }, \
+ { 62, 0x39 }, \
+ { 63, 0x07 }
+
+#define RT5592_DEF_RF \
+ { 1, 0x3f }, \
+ { 3, 0x08 }, \
+ { 5, 0x10 }, \
+ { 6, 0xe4 }, \
+ { 7, 0x00 }, \
+ { 14, 0x00 }, \
+ { 15, 0x00 }, \
+ { 16, 0x00 }, \
+ { 18, 0x03 }, \
+ { 19, 0x4d }, \
+ { 20, 0x10 }, \
+ { 21, 0x8d }, \
+ { 26, 0x82 }, \
+ { 28, 0x00 }, \
+ { 29, 0x10 }, \
+ { 33, 0xc0 }, \
+ { 34, 0x07 }, \
+ { 35, 0x12 }, \
+ { 47, 0x0c }, \
+ { 53, 0x22 }, \
+ { 63, 0x07 }
+
+#define RT5592_2GHZ_DEF_RF \
+ { 10, 0x90 }, \
+ { 11, 0x4a }, \
+ { 12, 0x52 }, \
+ { 13, 0x42 }, \
+ { 22, 0x40 }, \
+ { 24, 0x4a }, \
+ { 25, 0x80 }, \
+ { 27, 0x42 }, \
+ { 36, 0x80 }, \
+ { 37, 0x08 }, \
+ { 38, 0x89 }, \
+ { 39, 0x1b }, \
+ { 40, 0x0d }, \
+ { 41, 0x9b }, \
+ { 42, 0xd5 }, \
+ { 43, 0x72 }, \
+ { 44, 0x0e }, \
+ { 45, 0xa2 }, \
+ { 46, 0x6b }, \
+ { 48, 0x10 }, \
+ { 51, 0x3e }, \
+ { 52, 0x48 }, \
+ { 54, 0x38 }, \
+ { 56, 0xa1 }, \
+ { 57, 0x00 }, \
+ { 58, 0x39 }, \
+ { 60, 0x45 }, \
+ { 61, 0x91 }, \
+ { 62, 0x39 }
+
+#define RT5592_5GHZ_DEF_RF \
+ { 10, 0x97 }, \
+ { 11, 0x40 }, \
+ { 25, 0xbf }, \
+ { 27, 0x42 }, \
+ { 36, 0x00 }, \
+ { 37, 0x04 }, \
+ { 38, 0x85 }, \
+ { 40, 0x42 }, \
+ { 41, 0xbb }, \
+ { 42, 0xd7 }, \
+ { 45, 0x41 }, \
+ { 48, 0x00 }, \
+ { 57, 0x77 }, \
+ { 60, 0x05 }, \
+ { 61, 0x01 }
+
+#define RT5592_CHAN_5GHZ \
+ { 36, 64, 12, 0x2e }, \
+ { 100, 165, 12, 0x0e }, \
+ { 36, 64, 13, 0x22 }, \
+ { 100, 165, 13, 0x42 }, \
+ { 36, 64, 22, 0x60 }, \
+ { 100, 165, 22, 0x40 }, \
+ { 36, 64, 23, 0x7f }, \
+ { 100, 153, 23, 0x3c }, \
+ { 155, 165, 23, 0x38 }, \
+ { 36, 50, 24, 0x09 }, \
+ { 52, 64, 24, 0x07 }, \
+ { 100, 153, 24, 0x06 }, \
+ { 155, 165, 24, 0x05 }, \
+ { 36, 64, 39, 0x1c }, \
+ { 100, 138, 39, 0x1a }, \
+ { 140, 165, 39, 0x18 }, \
+ { 36, 64, 43, 0x5b }, \
+ { 100, 138, 43, 0x3b }, \
+ { 140, 165, 43, 0x1b }, \
+ { 36, 64, 44, 0x40 }, \
+ { 100, 138, 44, 0x20 }, \
+ { 140, 165, 44, 0x10 }, \
+ { 36, 64, 46, 0x00 }, \
+ { 100, 138, 46, 0x18 }, \
+ { 140, 165, 46, 0x08 }, \
+ { 36, 64, 51, 0xfe }, \
+ { 100, 124, 51, 0xfc }, \
+ { 126, 165, 51, 0xec }, \
+ { 36, 64, 52, 0x0c }, \
+ { 100, 138, 52, 0x06 }, \
+ { 140, 165, 52, 0x06 }, \
+ { 36, 64, 54, 0xf8 }, \
+ { 100, 165, 54, 0xeb }, \
+ { 36, 50, 55, 0x06 }, \
+ { 52, 64, 55, 0x04 }, \
+ { 100, 138, 55, 0x01 }, \
+ { 140, 165, 55, 0x00 }, \
+ { 36, 50, 56, 0xd3 }, \
+ { 52, 128, 56, 0xbb }, \
+ { 130, 165, 56, 0xab }, \
+ { 36, 64, 58, 0x15 }, \
+ { 100, 116, 58, 0x1d }, \
+ { 118, 165, 58, 0x15 }, \
+ { 36, 64, 59, 0x7f }, \
+ { 100, 138, 59, 0x3f }, \
+ { 140, 165, 59, 0x7c }, \
+ { 36, 64, 62, 0x15 }, \
+ { 100, 116, 62, 0x1d }, \
+ { 118, 165, 62, 0x15 }
union run_stats {
uint32_t raw;
diff --git a/sys/dev/usb/wlan/if_runvar.h b/sys/dev/usb/wlan/if_runvar.h
index 37ae3fa..cc6f44c 100644
--- a/sys/dev/usb/wlan/if_runvar.h
+++ b/sys/dev/usb/wlan/if_runvar.h
@@ -25,17 +25,11 @@
#define RUN_MAX_RXSZ \
MIN(4096, MJUMPAGESIZE)
-#if 0
- (sizeof (uint32_t) + \
- sizeof (struct rt2860_rxwi) + \
- sizeof (uint16_t) + \
- MCLBYTES + \
- sizeof (struct rt2870_rxd))
-#endif
+
/* NB: "11" is the maximum number of padding bytes needed for Tx */
#define RUN_MAX_TXSZ \
(sizeof (struct rt2870_txd) + \
- sizeof (struct rt2860_rxwi) + \
+ sizeof (struct rt2860_txwi) + \
MCLBYTES + 11)
#define RUN_TX_TIMEOUT 5000 /* ms */
@@ -170,7 +164,7 @@ struct run_softc {
uint16_t mac_ver;
uint16_t mac_rev;
- uint8_t rf_rev;
+ uint16_t rf_rev;
uint8_t freq;
uint8_t ntxchains;
uint8_t nrxchains;
diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c
index f238d0d..bf379be 100644
--- a/sys/dev/usb/wlan/if_uath.c
+++ b/sys/dev/usb/wlan/if_uath.c
@@ -1072,8 +1072,13 @@ uath_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
return (NULL);
vap = &uvp->vap;
/* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
+
+ if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
+ flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ /* out of memory */
+ free(uvp, M_80211_VAP);
+ return (NULL);
+ }
/* override state transition machine */
uvp->newstate = vap->iv_newstate;
diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c
index eff7922..3ea3cc1 100644
--- a/sys/dev/usb/wlan/if_upgt.c
+++ b/sys/dev/usb/wlan/if_upgt.c
@@ -1040,8 +1040,13 @@ upgt_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
return NULL;
vap = &uvp->vap;
/* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
+
+ if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
+ flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ /* out of memory */
+ free(uvp, M_80211_VAP);
+ return (NULL);
+ }
/* override state transition machine */
uvp->newstate = vap->iv_newstate;
diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c
index f3fa1ca..4a48cf5 100644
--- a/sys/dev/usb/wlan/if_ural.c
+++ b/sys/dev/usb/wlan/if_ural.c
@@ -589,8 +589,13 @@ ural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
return NULL;
vap = &uvp->vap;
/* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
+
+ if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
+ flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ /* out of memory */
+ free(uvp, M_80211_VAP);
+ return (NULL);
+ }
/* override state transition machine */
uvp->newstate = vap->iv_newstate;
@@ -1133,7 +1138,7 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
dur = ieee80211_ack_duration(ic->ic_rt, tp->mgmtrate,
ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- *(uint16_t *)wh->i_dur = htole16(dur);
+ USETW(wh->i_dur, dur);
/* tell hardware to add timestamp for probe responses */
if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
@@ -1324,7 +1329,7 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
dur = ieee80211_ack_duration(ic->ic_rt, rate,
ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- *(uint16_t *)wh->i_dur = htole16(dur);
+ USETW(wh->i_dur, dur);
}
ural_setup_tx_desc(sc, &data->desc, flags, m0->m_pkthdr.len, rate);
diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c
index 184317b..4e16579 100644
--- a/sys/dev/usb/wlan/if_urtw.c
+++ b/sys/dev/usb/wlan/if_urtw.c
@@ -1035,8 +1035,13 @@ urtw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
return (NULL);
vap = &uvp->vap;
/* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
+
+ if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
+ flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ /* out of memory */
+ free(uvp, M_80211_VAP);
+ return (NULL);
+ }
/* override state transition machine */
uvp->newstate = vap->iv_newstate;
@@ -1761,7 +1766,7 @@ urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
else
dur = URTW_ASIFS_TIME + acktime;
}
- *(uint16_t *)wh->i_dur = htole16(dur);
+ USETW(wh->i_dur, dur);
xferlen = m0->m_pkthdr.len;
xferlen += (sc->sc_flags & URTW_RTL8187B) ? (4 * 8) : (4 * 3);
diff --git a/sys/dev/usb/wlan/if_urtwn.c b/sys/dev/usb/wlan/if_urtwn.c
index 5f61cde..b8c2406 100644
--- a/sys/dev/usb/wlan/if_urtwn.c
+++ b/sys/dev/usb/wlan/if_urtwn.c
@@ -547,8 +547,13 @@ urtwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
return (NULL);
vap = &uvp->vap;
/* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
+
+ if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
+ flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ /* out of memory */
+ free(uvp, M_80211_VAP);
+ return (NULL);
+ }
/* override state transition machine */
uvp->newstate = vap->iv_newstate;
diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
index 3d3f269..01cdb33 100644
--- a/sys/dev/usb/wlan/if_zyd.c
+++ b/sys/dev/usb/wlan/if_zyd.c
@@ -488,9 +488,14 @@ zyd_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (zvp == NULL)
return (NULL);
vap = &zvp->vap;
+
/* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
+ if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
+ flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ /* out of memory */
+ free(zvp, M_80211_VAP);
+ return (NULL);
+ }
/* override state transition machine */
zvp->newstate = vap->iv_newstate;
OpenPOWER on IntegriCloud