svn commit: r259453 - in stable/10: share/man/man4 sys/dev/usb sys/dev/usb/wlan
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Dec 16 08:10:40 UTC 2013
Author: hselasky
Date: Mon Dec 16 08:10:38 2013
New Revision: 259453
URL: http://svnweb.freebsd.org/changeset/base/259453
Log:
MFC r238274, r246752, r256720, r256721, r256722, r256955, r257409
r257429, r257435, r257712, r257732, r257743, r257748, r257955
r257957, r257958, r258082, r258641, r258643, r258732, r258733,
r258840, r258919, r258921, r259029, r259030, r259031, r259032 and r259046:
- Add support for the MediaTek/Ralink RT5370/RT5372 chipset.
- Various minor USB WLAN fixes and improvements.
PR: usb/182936
Modified:
stable/10/share/man/man4/run.4
stable/10/share/man/man4/runfw.4
stable/10/sys/dev/usb/usbdevs
stable/10/sys/dev/usb/wlan/if_rsu.c
stable/10/sys/dev/usb/wlan/if_rum.c
stable/10/sys/dev/usb/wlan/if_run.c
stable/10/sys/dev/usb/wlan/if_runreg.h
stable/10/sys/dev/usb/wlan/if_runvar.h
stable/10/sys/dev/usb/wlan/if_uath.c
stable/10/sys/dev/usb/wlan/if_upgt.c
stable/10/sys/dev/usb/wlan/if_ural.c
stable/10/sys/dev/usb/wlan/if_urtw.c
stable/10/sys/dev/usb/wlan/if_urtwn.c
stable/10/sys/dev/usb/wlan/if_zyd.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/share/man/man4/run.4
==============================================================================
--- stable/10/share/man/man4/run.4 Mon Dec 16 06:56:38 2013 (r259452)
+++ stable/10/share/man/man4/run.4 Mon Dec 16 08:10:38 2013 (r259453)
@@ -16,7 +16,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 9, 2012
+.Dd November 11, 2013
.Dt RUN 4
.Os
.Sh NAME
@@ -52,7 +52,7 @@ runfw_load="YES"
The
.Nm
driver supports USB 2.0 wireless adapters based on the Ralink RT2700U,
-RT2800U and RT3000U chipsets.
+RT2800U, RT3000U and RT3900E chipsets.
.Pp
The RT2700U chipset consists of two integrated chips, an RT2770 MAC/BBP and
an RT2720 (1T2R) or RT2750 (dual-band 1T2R) radio transceiver.
@@ -64,6 +64,9 @@ The RT3000U is a single-chip solution ba
an RT3020 (1T1R), RT3021 (1T2R) or RT3022 (2T2R) single-band radio
transceiver.
.Pp
+The RT3900E is a single-chip solution based on an RT5390 MAC/BBP and
+an RT5370 (1T1R) or RT5372 (2T2R) single-band radio transceiver.
+.Pp
These are the modes the
.Nm
driver can operate in:
@@ -129,7 +132,8 @@ driver supports the following wireless a
.It Corega CG-WLUSB300AGN
.It Corega CG-WLUSB300GNM
.It D-Link DWA-130 rev B1
-.It D-Link DWA-140 rev B1, B2
+.It D-Link DWA-140 rev B1, B2, B3
+.It D-Link DWA-160 rev B2
.It DrayTek Vigor N61
.It Edimax EW-7711UAn
.It Edimax EW-7711UTn
@@ -156,6 +160,8 @@ driver supports the following wireless a
.It SMC SMCWUSBS-N2
.It Sweex LW303
.It Sweex LW313
+.It TP-LINK TL-WDN3200
+.It TP-LINK TL-WN727N v3
.It Unex DNUR-81
.It Unex DNUR-82
.It ZyXEL NWD210N
Modified: stable/10/share/man/man4/runfw.4
==============================================================================
--- stable/10/share/man/man4/runfw.4 Mon Dec 16 06:56:38 2013 (r259452)
+++ stable/10/share/man/man4/runfw.4 Mon Dec 16 08:10:38 2013 (r259453)
@@ -18,7 +18,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 12, 2011
+.Dd November 11, 2013
.Dt RUNFW 4
.Os
.Sh NAME
@@ -43,7 +43,7 @@ runfw_load="YES"
.Ed
.Sh DESCRIPTION
This module provides firmware sets for the Ralink RT2700U,
-RT2800U and RT3000U chip based USB WiFi adapters.
+RT2800U, RT3000U and RT3900E chip based USB WiFi adapters.
Please read Ralink's license, src/sys/contrib/dev/run/LICENSE.
.Sh SEE ALSO
.Xr run 4 ,
Modified: stable/10/sys/dev/usb/usbdevs
==============================================================================
--- stable/10/sys/dev/usb/usbdevs Mon Dec 16 06:56:38 2013 (r259452)
+++ stable/10/sys/dev/usb/usbdevs Mon Dec 16 08:10:38 2013 (r259453)
@@ -1549,6 +1549,8 @@ product DLINK DWLG122 0x3c00 DWL-G122 b
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
Modified: stable/10/sys/dev/usb/wlan/if_rsu.c
==============================================================================
--- stable/10/sys/dev/usb/wlan/if_rsu.c Mon Dec 16 06:56:38 2013 (r259452)
+++ stable/10/sys/dev/usb/wlan/if_rsu.c Mon Dec 16 08:10:38 2013 (r259453)
@@ -480,8 +480,13 @@ rsu_vap_create(struct ieee80211com *ic,
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, u
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);
Modified: stable/10/sys/dev/usb/wlan/if_rum.c
==============================================================================
--- stable/10/sys/dev/usb/wlan/if_rum.c Mon Dec 16 06:56:38 2013 (r259452)
+++ stable/10/sys/dev/usb/wlan/if_rum.c Mon Dec 16 08:10:38 2013 (r259453)
@@ -604,8 +604,13 @@ rum_vap_create(struct ieee80211com *ic,
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
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
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);
Modified: stable/10/sys/dev/usb/wlan/if_run.c
==============================================================================
--- stable/10/sys/dev/usb/wlan/if_run.c Mon Dec 16 06:56:38 2013 (r259452)
+++ stable/10/sys/dev/usb/wlan/if_run.c Mon Dec 16 08:10:38 2013 (r259453)
@@ -2,6 +2,7 @@
* Copyright (c) 2008,2010 Damien Bergamini <damien.bergamini at free.fr>
* ported to FreeBSD by Akinori Furukoshi <moonlightakkiy at yahoo.ca>
* USB Consulting, Hans Petter Selasky <hselasky at 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_callba
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
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
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 ru
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 ifne
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,
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,
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, uint
}
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
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, struc
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, struc
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, struc
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, struc
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 *xf
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 *xf
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 *p
}
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, st
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, st
/* 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
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
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
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
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
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 *
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 *
} 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 *
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 *
}
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
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);
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list