summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2017-01-31 09:21:47 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2017-01-31 09:21:47 +0000
commiteebc436e370856a6148b4778f7d4b128c31012de (patch)
treed73a69e69ddf5a506af587498ba998e7ca2c97b8 /sys/dev/ic
parentc41c195af28a253d2f316d3c4428f0818520da88 (diff)
Clean up code in rtwn(4)/urtwn(4) which handles EDCA parameters:
Get EDCA params from net80211 instead of hardcoding them. Enable hardware management of EDCA AC queues. Handling of frame collisions with EDCA involves random backoffs. I found a register that looks like a seed for the pseudo-RNG involved in computing backoffs. Feed it with arc4random() during initialization. Add a comment to hint at the meaning of numbers written to SIFS registers, and rename some SIFS registers to better names found in Linux. ok mpi@
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/r92creg.h15
-rw-r--r--sys/dev/ic/rtwn.c69
2 files changed, 47 insertions, 37 deletions
diff --git a/sys/dev/ic/r92creg.h b/sys/dev/ic/r92creg.h
index ed43bca6850..cfaedfbd42b 100644
--- a/sys/dev/ic/r92creg.h
+++ b/sys/dev/ic/r92creg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: r92creg.h,v 1.4 2017/01/08 05:48:27 stsp Exp $ */
+/* $OpenBSD: r92creg.h,v 1.5 2017/01/31 09:21:46 stsp Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -218,8 +218,8 @@
#define R92C_BSSID 0x618
#define R92C_MAR 0x620
#define R92C_MAC_SPEC_SIFS 0x63a
-#define R92C_R2T_SIFS 0x63c
-#define R92C_T2T_SIFS 0x63e
+#define R92C_RESP_SIFS_CCK 0x63c
+#define R92C_RESP_SIFS_OFDM 0x63e
#define R92C_ACKTO 0x640
#define R92C_CAMCMD 0x670
#define R92C_CAMWRITE 0x674
@@ -506,6 +506,15 @@
#define R92C_EDCA_PARAM_TXOP_M 0xffff0000
#define R92C_EDCA_PARAM_TXOP_S 16
+/* Bits for R92C_ACMHWCTRL */
+#define R92C_ACMHW_HWEN 0x01
+#define R92C_ACMHW_BEQEN 0x02
+#define R92C_ACMHW_VIQEN 0x04
+#define R92C_ACMHW_VOQEN 0x08
+#define R92C_ACMHW_BEQSTATUS 0x10
+#define R92C_ACMHW_VIQSTATUS 0x20
+#define R92C_ACMHW_VOQSTATUS 0x40
+
/* Bits for R92C_TXPAUSE. */
#define R92C_TXPAUSE_AC_VO 0x01
#define R92C_TXPAUSE_AC_VI 0x02
diff --git a/sys/dev/ic/rtwn.c b/sys/dev/ic/rtwn.c
index c9dff3f134a..ba42c39ea29 100644
--- a/sys/dev/ic/rtwn.c
+++ b/sys/dev/ic/rtwn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtwn.c,v 1.15 2017/01/30 21:54:30 stsp Exp $ */
+/* $OpenBSD: rtwn.c,v 1.16 2017/01/31 09:21:46 stsp Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -901,10 +901,7 @@ rtwn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
R92C_BCN_CTRL_DIS_TSF_UDT0);
/* Reset EDCA parameters. */
- rtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002f3217);
- rtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005e4317);
- rtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x00105320);
- rtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a444);
+ rtwn_edca_init(sc);
rtwn_updateslot(ic);
rtwn_update_short_preamble(ic);
@@ -1010,15 +1007,9 @@ rtwn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
/* Enable TSF synchronization. */
rtwn_tsf_sync_enable(sc);
- rtwn_write_1(sc, R92C_SIFS_CCK + 1, 10);
- rtwn_write_1(sc, R92C_SIFS_OFDM + 1, 10);
- rtwn_write_1(sc, R92C_SPEC_SIFS + 1, 10);
- rtwn_write_1(sc, R92C_MAC_SPEC_SIFS + 1, 10);
- rtwn_write_1(sc, R92C_R2T_SIFS + 1, 10);
- rtwn_write_1(sc, R92C_T2T_SIFS + 1, 10);
-
/* Intialize rate adaptation. */
rtwn_ra_init(sc);
+
/* Turn link LED on. */
rtwn_set_led(sc, RTWN_LED_LINK, 1);
@@ -1078,12 +1069,15 @@ rtwn_updateedca(struct ieee80211com *ic)
struct ieee80211_edca_ac_params *ac;
int s, aci, aifs, slottime;
+ if (ic->ic_flags & IEEE80211_F_SHSLOT)
+ slottime = 9; /* XXX needs a macro in ieee80211.h */
+ else
+ slottime = IEEE80211_DUR_DS_SLOT;
s = splnet();
- slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
for (aci = 0; aci < EDCA_NUM_AC; aci++) {
ac = &ic->ic_edca_ac[aci];
/* AIFS[AC] = AIFSN[AC] * aSlotTime + aSIFSTime. */
- aifs = ac->ac_aifsn * slottime + 10;
+ aifs = ac->ac_aifsn * slottime + IEEE80211_DUR_DS_SIFS;
rtwn_write_4(sc, aci2reg[aci],
SM(R92C_EDCA_PARAM_TXOP, ac->ac_txoplimit) |
SM(R92C_EDCA_PARAM_ECWMIN, ac->ac_ecwmin) |
@@ -1708,26 +1702,33 @@ rtwn_rxfilter_init(struct rtwn_softc *sc)
void
rtwn_edca_init(struct rtwn_softc *sc)
{
- /* XXX Use the same values for PCI and USB? */
- if (sc->chip & RTWN_CHIP_PCI) {
- rtwn_write_2(sc, R92C_SPEC_SIFS, 0x1010);
- rtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x1010);
- rtwn_write_2(sc, R92C_SIFS_CCK, 0x1010);
- rtwn_write_2(sc, R92C_SIFS_OFDM, 0x0e0e);
- rtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x005ea42b);
- rtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a44f);
- rtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005e4322);
- rtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002f3222);
- } else if (sc->chip & RTWN_CHIP_USB) {
- rtwn_write_2(sc, R92C_SPEC_SIFS, 0x100a);
- rtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x100a);
- rtwn_write_2(sc, R92C_SIFS_CCK, 0x100a);
- rtwn_write_2(sc, R92C_SIFS_OFDM, 0x100a);
- rtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x005ea42b);
- rtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a44f);
- rtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005ea324);
- rtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002fa226);
- }
+ struct ieee80211com *ic = &sc->sc_ic;
+ int mode, aci;
+
+ /* Set SIFS; 0x10 = 16 usec (SIFS 11g), 0x0a = 10 usec (SIFS 11b) */
+ rtwn_write_2(sc, R92C_SPEC_SIFS, 0x100a);
+ rtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x100a);
+ rtwn_write_2(sc, R92C_SIFS_CCK, 0x100a);
+ rtwn_write_2(sc, R92C_SIFS_OFDM, 0x100a);
+ rtwn_write_2(sc, R92C_RESP_SIFS_CCK, 0x100a);
+ rtwn_write_2(sc, R92C_RESP_SIFS_OFDM, 0x100a);
+
+ if (ic->ic_curmode == IEEE80211_MODE_AUTO)
+ mode = IEEE80211_MODE_11G; /* XXX */
+ else
+ mode = ic->ic_curmode;
+ for (aci = 0; aci < EDCA_NUM_AC; aci++)
+ memcpy(&ic->ic_edca_ac[aci], &ieee80211_edca_table[mode][aci],
+ sizeof(struct ieee80211_edca_ac_params));
+ rtwn_updateedca(ic);
+
+ rtwn_write_4(sc, R92C_FAST_EDCA_CTRL, 0x086666); /* linux magic */
+
+ rtwn_write_4(sc, R92C_EDCA_RANDOM_GEN, arc4random());
+
+ /* Enable hardware AC queue management. */
+ rtwn_write_1(sc, R92C_ACMHWCTRL, R92C_ACMHW_HWEN | R92C_ACMHW_BEQEN |
+ R92C_ACMHW_VIQEN | R92C_ACMHW_VOQEN);
}
void