summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2009-02-06 18:43:23 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2009-02-06 18:43:23 +0000
commit70ec42f477f110940296e905718a4c522e69c93c (patch)
tree0f6faf8ca47ce9be12d64c1746b2cd8e49de320c
parent55481656166fa78d17d1bbafe87cc4f96f72d051 (diff)
- fix run_mcu_cmd(). it has the side-effect of fixing LEDs.
- fix run_rt3070_rf_write() for RT3070 - fix HW WEP for those who still care - add quirks required for RT3070+RT3020 committed over an EDIMAX EW-7711UAn (RT3070+RT3020)
-rw-r--r--sys/dev/usb/if_run.c102
1 files changed, 59 insertions, 43 deletions
diff --git a/sys/dev/usb/if_run.c b/sys/dev/usb/if_run.c
index 5e37db62208..c4287af0ab2 100644
--- a/sys/dev/usb/if_run.c
+++ b/sys/dev/usb/if_run.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_run.c,v 1.6 2009/01/26 19:18:52 damien Exp $ */
+/* $OpenBSD: if_run.c,v 1.7 2009/02/06 18:43:22 damien Exp $ */
/*-
* Copyright (c) 2008,2009 Damien Bergamini <damien.bergamini@free.fr>
@@ -65,8 +65,6 @@
#include <dev/ic/rt2860reg.h> /* shared with ral(4) */
#include <dev/usb/if_runvar.h>
-#include <dev/rndvar.h>
-
#ifdef USB_DEBUG
#define RUN_DEBUG
#endif
@@ -223,6 +221,7 @@ void run_start(struct ifnet *);
void run_watchdog(struct ifnet *);
int run_ioctl(struct ifnet *, u_long, caddr_t);
void run_select_chan_group(struct run_softc *, int);
+void run_set_rx_antenna(struct run_softc *, int);
void run_rt2870_set_chan(struct run_softc *, u_int);
void run_rt3070_set_chan(struct run_softc *, u_int);
int run_set_chan(struct run_softc *, struct ieee80211_channel *);
@@ -903,7 +902,7 @@ run_rt3070_rf_write(struct run_softc *sc, uint8_t reg, uint8_t val)
if (ntries == 10)
return ETIMEDOUT;
- tmp |= RT3070_RF_WRITE | RT3070_RF_KICK | reg << 8 | val;
+ tmp = RT3070_RF_WRITE | RT3070_RF_KICK | reg << 8 | val;
return run_write(sc, RT3070_RF_CSR_CFG, tmp);
}
@@ -976,7 +975,7 @@ run_mcu_cmd(struct run_softc *sc, uint8_t cmd, uint16_t arg)
if (ntries == 100)
return ETIMEDOUT;
- tmp |= RT2860_H2M_BUSY | RT2860_TOKEN_NO_INTR << 16 | arg;
+ tmp = RT2860_H2M_BUSY | RT2860_TOKEN_NO_INTR << 16 | arg;
if ((error = run_write(sc, RT2860_H2M_MAILBOX, tmp)) == 0)
error = run_write(sc, RT2860_HOST_CMD, cmd);
return error;
@@ -1284,8 +1283,8 @@ run_task(void *arg)
s = splusb();
while (ring->next != ring->cur) {
cmd = &ring->cmd[ring->next];
- /* callback */
splx(s);
+ /* callback */
cmd->cb(sc, cmd->data);
s = splusb();
ring->queued--;
@@ -1468,7 +1467,7 @@ run_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
/* do it in a process context */
cmd.key = *k;
- cmd.associd = ni->ni_associd;
+ cmd.associd = (ni != NULL) ? ni->ni_associd : 0;
run_do_async(sc, run_set_key_cb, &cmd, sizeof cmd);
return 0;
}
@@ -1512,23 +1511,18 @@ run_set_key_cb(struct run_softc *sc, void *arg)
run_write_region_1(sc, base, k->k_key, 16);
run_write_region_1(sc, base + 16, &k->k_key[24], 8);
run_write_region_1(sc, base + 24, &k->k_key[16], 8);
- } else
- run_write_region_1(sc, base, k->k_key, k->k_len);
+ } else {
+ /* roundup len to 16-bit: XXX fix write_region_1() instead */
+ run_write_region_1(sc, base, k->k_key, (k->k_len + 1) & ~1);
+ }
if (!(k->k_flags & IEEE80211_KEY_GROUP) ||
(k->k_flags & IEEE80211_KEY_TX)) {
/* set initial packet number in IV+EIV */
- if (k->k_cipher == IEEE80211_CIPHER_WEP40 ||
- k->k_cipher == IEEE80211_CIPHER_WEP104) {
- uint32_t val = arc4random();
- /* skip weak IVs from Fluhrer/Mantin/Shamir */
- if (val >= 0x03ff00 && (val & 0xf8ff00) == 0x00ff00)
- val += 0x000100;
- iv[0] = val;
- iv[1] = val >> 8;
- iv[2] = val >> 16;
- iv[3] = k->k_id << 6;
- iv[4] = iv[5] = iv[6] = iv[7] = 0;
+ if ((k->k_cipher == IEEE80211_CIPHER_WEP40 ||
+ k->k_cipher == IEEE80211_CIPHER_WEP104)) {
+ memset(iv, 0, sizeof iv);
+ iv[3] = sc->sc_ic.ic_def_txkey << 6;
} else {
if (k->k_cipher == IEEE80211_CIPHER_TKIP) {
iv[0] = k->k_tsc >> 8;
@@ -1575,7 +1569,7 @@ run_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
/* do it in a process context */
cmd.key = *k;
- cmd.associd = ni->ni_associd;
+ cmd.associd = (ni != NULL) ? ni->ni_associd : 0;
run_do_async(sc, run_delete_key_cb, &cmd, sizeof cmd);
}
@@ -2354,6 +2348,24 @@ run_rt3070_set_chan(struct run_softc *sc, u_int chan)
run_rt3070_rf_write(sc, 7, rf | 0x01);
}
+void
+run_set_rx_antenna(struct run_softc *sc, int aux)
+{
+ uint32_t tmp;
+
+ if (aux) {
+ run_read(sc, RT2860_PCI_EECTRL, &tmp);
+ run_write(sc, RT2860_PCI_EECTRL, tmp & ~RT2860_C);
+ run_read(sc, RT2860_GPIO_CTRL, &tmp);
+ run_write(sc, RT2860_GPIO_CTRL, (tmp & ~0x0808) | 0x08);
+ } else {
+ run_read(sc, RT2860_PCI_EECTRL, &tmp);
+ run_write(sc, RT2860_PCI_EECTRL, tmp | RT2860_C);
+ run_read(sc, RT2860_GPIO_CTRL, &tmp);
+ run_write(sc, RT2860_GPIO_CTRL, tmp & ~0x0808);
+ }
+}
+
int
run_set_chan(struct run_softc *sc, struct ieee80211_channel *c)
{
@@ -2548,16 +2560,17 @@ run_bbp_init(struct run_softc *sc)
}
/* fix BBP84 for RT2860E */
- if ((sc->mac_rev & 0xffff) != 0x0101)
+ if ((sc->mac_rev >> 16) == 0x2860 && (sc->mac_rev & 0xffff) != 0x0101)
run_bbp_write(sc, 84, 0x19);
if ((sc->mac_rev >> 16) >= 0x3070) {
- run_bbp_write(sc, 70, 0x0a);
- run_bbp_write(sc, 84, 0x99);
- run_bbp_write(sc, 105, 0x05);
+ run_bbp_write(sc, 79, 0x13);
+ run_bbp_write(sc, 80, 0x05);
+ run_bbp_write(sc, 81, 0x33);
+ /* XXX RT3090 needs more */
} else if (sc->mac_rev == 0x28600100) {
- run_bbp_write(sc, 69, 0x16);
- run_bbp_write(sc, 73, 0x12);
+ run_bbp_write(sc, 69, 0x16);
+ run_bbp_write(sc, 73, 0x12);
}
return 0;
}
@@ -2604,6 +2617,10 @@ run_rt3070_rf_init(struct run_softc *sc)
run_write(sc, RT3070_GPIO_SWITCH, tmp & ~0x20);
}
+ /* select 20MHz bandwidth */
+ run_rt3070_rf_read(sc, 31, &rf);
+ run_rt3070_rf_write(sc, 31, rf & ~0x20);
+
/* calibrate filter for 20MHz bandwidth */
sc->rf24_20mhz = 0x1f; /* default value */
run_rt3070_filter_calib(sc, 0x07, 0x16, &sc->rf24_20mhz);
@@ -2696,17 +2713,16 @@ run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target,
run_bbp_read(sc, 55, &bbp55_sb);
delta = bbp55_pb - bbp55_sb;
- if (delta < target)
- rf24++;
- else if (delta == target)
- rf24++;
- else
+ if (delta > target)
break;
/* reprogram filter */
+ rf24++;
run_rt3070_rf_write(sc, 24, rf24);
}
if (ntries < 100) {
+ if (rf24 != init)
+ rf24--; /* backtrack */
*val = rf24;
run_rt3070_rf_write(sc, 24, rf24);
}
@@ -2776,7 +2792,7 @@ run_init(struct ifnet *ifp)
struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
uint8_t bbp1, bbp3;
- int i, error, qid, wcid, ridx, ntries;
+ int i, error, qid, ridx, ntries;
for (ntries = 0; ntries < 100; ntries++) {
if ((error = run_read(sc, RT2860_ASIC_VER_ID, &tmp)) != 0)
@@ -2861,7 +2877,7 @@ run_init(struct ifnet *ifp)
run_write(sc, RT2860_TX_SW_CFG0,
4 << RT2860_DLY_PAPE_EN_SHIFT);
run_write(sc, RT2860_TX_SW_CFG1, 0);
- run_write(sc, RT2860_TX_SW_CFG2, 0);
+ run_write(sc, RT2860_TX_SW_CFG2, 0x1f);
}
/* wait while MAC is busy */
@@ -2893,15 +2909,11 @@ run_init(struct ifnet *ifp)
run_write(sc, RT2860_BCN_TIME_CFG, tmp);
/* clear RX WCID search table */
- for (wcid = 0; wcid <= RT2870_WCID_MAX; wcid++) {
- /* etherbroadcast followed by BA session mask */
- static const uint8_t entry[] =
- { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 };
- run_write_region_1(sc, RT2860_WCID_ENTRY(wcid),
- entry, sizeof entry);
- }
+ run_set_region_4(sc, RT2860_WCID_ENTRY(0), 0, 512);
/* clear WCID attribute table */
- run_set_region_4(sc, RT2860_WCID_ATTR(0), 1, 8 * 32);
+ run_set_region_4(sc, RT2860_WCID_ATTR(0), 0, 8 * 32);
+ /* clear shared key table */
+ run_set_region_4(sc, RT2860_SKEY(0, 0), 0, 8 * 32);
/* clear shared key mode */
run_set_region_4(sc, RT2860_SKEY_MODE_0_7, 0, 4);
@@ -2909,7 +2921,7 @@ run_init(struct ifnet *ifp)
tmp = (tmp & ~0xff) | 0x1e;
run_write(sc, RT2860_US_CYC_CNT, tmp);
- if ((sc->mac_rev & 0xffff) != 0x0101)
+ if ((sc->mac_rev >> 16) == 0x2860 && (sc->mac_rev & 0xffff) != 0x0101)
run_write(sc, RT2860_TXOP_CTRL_CFG, 0x0000583f);
run_write(sc, RT2860_WMM_TXOP0_CFG, 0);
@@ -2922,6 +2934,10 @@ run_init(struct ifnet *ifp)
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)
+ run_set_rx_antenna(sc, 0);
+
/* send LEDs operating mode to microcontroller */
(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED1, sc->led[0]);
(void)run_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1]);