Add support for the MediaTek/Ralink RT5370/RT5372 chipset.

Tested with the TP-Link TL-WN727N (RT5370) and the D-Link DWA-140 (RT5372)
on i386/amd64/arm with WPA.
This commit is contained in:
Kevin Lo 2013-11-11 09:47:33 +00:00
parent 0a37d4a300
commit 64891211ca
4 changed files with 637 additions and 154 deletions

View File

@ -1553,6 +1553,7 @@ 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 DWA127 0x3c1b DWA-127 Wireless Adapter
product DLINK DSB650C 0x4000 10Mbps Ethernet
product DLINK DSB650TX1 0x4001 10/100 Ethernet

View File

@ -20,7 +20,7 @@
__FBSDID("$FreeBSD$");
/*-
* Ralink Technology RT2700U/RT2800U/RT3000U chipset driver.
* Ralink Technology RT2700U/RT2800U/RT3000U/RT3900E chipset driver.
* http://www.ralinktech.com/
*/
@ -75,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
@ -174,6 +172,7 @@ 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(DLINK2, DWA130),
RUN_DEV(DLINK2, RT2870_1),
RUN_DEV(DLINK2, RT2870_2),
@ -257,6 +256,7 @@ 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, RT8070),
RUN_DEV(SAMSUNG, WIS09ABGN),
RUN_DEV(SAMSUNG2, RT2870_1),
@ -350,7 +350,7 @@ 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]);
@ -362,7 +362,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 *);
@ -394,6 +394,7 @@ 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 int run_set_chan(struct run_softc *, struct ieee80211_channel *);
static void run_set_channel(struct ieee80211com *);
static void run_scan_start(struct ieee80211com *);
@ -417,12 +418,15 @@ 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 *);
@ -440,6 +444,8 @@ static const struct {
uint8_t val;
} rt2860_def_bbp[] = {
RT2860_DEF_BBP
},rt5390_def_bbp[] = {
RT5390_DEF_BBP
};
static const struct rfprog {
@ -462,6 +468,10 @@ static const struct {
RT3070_DEF_RF
},rt3572_def_rf[] = {
RT3572_DEF_RF
},rt5390_def_rf[] = {
RT5390_DEF_RF
},rt5392_def_rf[] = {
RT5392_DEF_RF
};
static const struct usb_config run_config[RUN_N_XFER] = {
@ -665,7 +675,7 @@ run_attach(device_t self)
sc->rf_rev == RT2860_RF_2850 ||
sc->rf_rev == RT3070_RF_3052) {
/* set supported .11a rates */
for (i = 14; i < N(rt2860_rf2850); i++) {
for (i = 14; i < nitems(rt2860_rf2850); i++) {
uint8_t chan = rt2860_rf2850[i].chan;
ic->ic_channels[ic->ic_nchans].ic_freq =
ieee80211_ieee2mhz(chan, IEEE80211_CHAN_A);
@ -1170,32 +1180,13 @@ 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;
/*
* 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);
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));
#endif
}
@ -1453,7 +1444,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";
@ -1465,6 +1456,8 @@ run_get_rf(int rev)
case RT3070_RF_3021: return "RT3021";
case RT3070_RF_3022: return "RT3022";
case RT3070_RF_3052: return "RT3052";
case RT5390_RF_5370: return "RT5370";
case RT5390_RF_5372: return "RT5372";
}
return ("unknown");
}
@ -1501,21 +1494,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);
}
}
}
@ -1541,7 +1538,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)
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) {
@ -1561,11 +1562,15 @@ run_read_eeprom(struct run_softc *sc)
sc->nrxchains = 2;
}
} else {
sc->rf_rev = (val >> 8) & 0xf;
if (sc->mac_ver >= 0x5390) {
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 */
@ -1589,16 +1594,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]);
}
@ -3544,15 +3562,24 @@ 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 < 0x5390)
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 >= 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)
@ -3878,19 +3905,142 @@ run_rt3572_set_chan(struct run_softc *sc, u_int chan)
run_delay(sc, 2);
}
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 >= 1) && (chan <= 4))
rf = 0x0f;
else if ((chan >= 5) && (chan <= 7))
rf = 0x0e;
else if ((chan >= 8) && (chan <= 14))
rf = 0x0d;
run_rt3070_rf_write(sc, 23, rf);
if ((chan >= 1) && (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 if ((chan >= 11) && (chan <= 14))
rf = 0x08;
run_rt3070_rf_write(sc, 59, rf);
} else {
if ((chan >= 1) && (chan <= 11))
rf = 0x0f;
else if ((chan >= 12) && (chan <= 14))
rf = 0x0b;
run_rt3070_rf_write(sc, 59, rf);
}
} else {
/* Fix for RT5390F. */
if (sc->mac_rev >= 0x0502) {
if ((chan >= 1) && (chan <= 11))
rf = 0x43;
else if ((chan >= 12) && (chan <= 14))
rf = 0x23;
run_rt3070_rf_write(sc, 55, rf);
if ((chan >= 1) && (chan <= 11))
rf = 0x0f;
else if (chan == 12)
rf = 0x0d;
else if ((chan >= 13) && (chan <= 14))
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_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);
}
if (sc->rf_rev == RT3070_RF_3020) {
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);
}
if (sc->rf_rev == RT3070_RF_3020) {
run_mcu_cmd(sc, RT2860_MCU_CMD_ANTSEL, 1);
run_read(sc, RT2860_GPIO_CTRL, &tmp);
run_write(sc, RT2860_GPIO_CTRL, tmp & ~0x0808);
}
}
}
@ -3904,7 +4054,9 @@ run_set_chan(struct run_softc *sc, struct ieee80211_channel *c)
if (chan == 0 || chan == IEEE80211_CHAN_ANY)
return (EINVAL);
if (sc->mac_ver == 0x3572)
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);
@ -4184,7 +4336,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;
@ -4356,6 +4509,35 @@ 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 bbp4;
/* Avoid data lost and CRC error. */
run_bbp_read(sc, 4, &bbp4);
run_bbp_write(sc, 4, bbp4 | 0x40);
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);
}
/* Disable hardware antenna diversity. */
if (sc->mac_ver == 0x5390)
run_bbp_write(sc, 154, 0);
}
static int
run_bbp_init(struct run_softc *sc)
{
@ -4373,9 +4555,13 @@ 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 */
@ -4408,12 +4594,12 @@ 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);
}
@ -4537,6 +4723,62 @@ 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;
if (sc->mac_ver == 0x5392)
run_rt3070_rf_write(sc, 2, 0x80);
else {
run_rt3070_rf_read(sc, 2, &rf);
/* Toggle RF R2 to initiate calibration. */
run_rt3070_rf_write(sc, 2, rf | 0x80);
run_delay(sc, 10);
run_rt3070_rf_write(sc, 2, rf & ~0x80);
}
/* Initialize RF registers to default value. */
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 = 0x2f; /* default value */
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)
@ -4566,7 +4808,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);
@ -4608,7 +4850,45 @@ 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);
/* 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 | 0x40);
run_rt3070_rf_read(sc, 30, &rf);
rf = (rf & ~0x18) | 0x10;
run_rt3070_rf_write(sc, 30, rf);
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);
@ -4672,7 +4952,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;
@ -4691,13 +4971,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);
@ -4727,6 +5007,20 @@ run_txrx_enable(struct run_softc *sc)
return (0);
}
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)
{
@ -4800,13 +5094,20 @@ 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 == 0x5392) {
run_write(sc, RT2860_TX_SW_CFG0, 0x00000404);
run_write(sc, RT2860_MAX_LEN_CFG, 0x00002fff);
run_write(sc, RT2860_HT_FBK_CFG1, 0xedcb4980);
run_write(sc, RT2860_LG_FBK_CFG0, 0xedcba322);
} else if (sc->mac_ver == 0x5390) {
run_write(sc, RT2860_TX_SW_CFG0, 0x00000404);
} 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);
@ -4863,14 +5164,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 */
@ -4878,7 +5181,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 */
@ -4972,6 +5277,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);
@ -4999,8 +5322,6 @@ run_stop(void *arg)
for (i = 0; i != RUN_EP_QUEUES; i++)
run_unsetup_tx_list(sc, &sc->sc_epq[i]);
return;
}
static void
@ -5026,7 +5347,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);

View File

@ -209,6 +209,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)
@ -688,6 +689,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 +707,14 @@
/* possible flags for RT3020 RF register 21 */
#define RT3070_RX_LO2 (1 << 3)
/* 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)
/* RT2860 TX descriptor */
struct rt2860_txd {
@ -839,15 +849,17 @@ struct rt2860_rxwi {
#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 RT5390_RF_5370 0x5370 /* 1T1R */
#define RT5390_RF_5372 0x5372 /* 2T2R */
/* USB commands for RT2870 only */
#define RT2870_RESET 1
@ -1013,63 +1025,94 @@ 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 }
/*
* 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 }, \
@ -1180,6 +1223,124 @@ 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 }
union run_stats {
uint32_t raw;

View File

@ -170,7 +170,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;