aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDamien Bergamini <damien@FreeBSD.org>2006-01-29 12:35:26 +0000
committerDamien Bergamini <damien@FreeBSD.org>2006-01-29 12:35:26 +0000
commit0cfa855f810040b4a55f65b903935bc0bbe228df (patch)
treefe485d2ff2ce33284236a0444b94c4b05fdda62e /sys
parent84f55b29e90600005d9864731644845e627932d5 (diff)
downloadsrc-0cfa855f810040b4a55f65b903935bc0bbe228df.tar.gz
src-0cfa855f810040b4a55f65b903935bc0bbe228df.zip
o Fix short preamble support
o Fix contention window o Feed rx rate to radiotap o Clean ral_setup_txdesc (sync w/ ural) o s/ic_ibss_chan/ic_curchan/
Notes
Notes: svn path=/head/; revision=154993
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ral/if_ral.c148
-rw-r--r--sys/dev/ral/if_ralreg.h3
-rw-r--r--sys/dev/ral/if_ralvar.h4
3 files changed, 95 insertions, 60 deletions
diff --git a/sys/dev/ral/if_ral.c b/sys/dev/ral/if_ral.c
index bc47bb2a7fe6..75171b6890a5 100644
--- a/sys/dev/ral/if_ral.c
+++ b/sys/dev/ral/if_ral.c
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*-
- * Copyright (c) 2005
+ * Copyright (c) 2005, 2006
* Damien Bergamini <damien.bergamini@free.fr>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -105,6 +105,7 @@ static void ral_rx_intr(struct ral_softc *);
static void ral_beacon_expire(struct ral_softc *);
static void ral_wakeup_expire(struct ral_softc *);
static void ral_intr(void *);
+static uint8_t ral_rxrate(struct ral_rx_desc *);
static int ral_ack_rate(struct ieee80211com *, int);
static uint16_t ral_txtime(int, int, uint32_t);
static uint8_t ral_plcp_signal(int);
@@ -134,6 +135,7 @@ static void ral_disable_rf_tune(struct ral_softc *);
static void ral_enable_tsf_sync(struct ral_softc *);
static void ral_update_plcp(struct ral_softc *);
static void ral_update_slot(struct ifnet *);
+static void ral_set_basicrates(struct ral_softc *);
static void ral_update_led(struct ral_softc *, int, int);
static void ral_set_bssid(struct ral_softc *, uint8_t *);
static void ral_set_macaddr(struct ral_softc *, uint8_t *);
@@ -292,7 +294,6 @@ static const struct {
uint32_t r2;
uint32_t r4;
} ral_rf5222[] = {
- /* channels in the 2.4GHz band */
{ 1, 0x08808, 0x0044d, 0x00282 },
{ 2, 0x08808, 0x0044e, 0x00282 },
{ 3, 0x08808, 0x0044f, 0x00282 },
@@ -308,7 +309,6 @@ static const struct {
{ 13, 0x08808, 0x00469, 0x00282 },
{ 14, 0x08808, 0x0046b, 0x00286 },
- /* channels in the 5.2GHz band */
{ 36, 0x08804, 0x06225, 0x00287 },
{ 40, 0x08804, 0x06226, 0x00287 },
{ 44, 0x08804, 0x06227, 0x00287 },
@@ -973,8 +973,9 @@ static int
ral_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
{
struct ral_softc *sc = ic->ic_ifp->if_softc;
- struct mbuf *m;
enum ieee80211_state ostate;
+ struct ieee80211_node *ni;
+ struct mbuf *m;
int error = 0;
ostate = ic->ic_state;
@@ -1010,24 +1011,17 @@ ral_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
case IEEE80211_S_RUN:
ral_set_chan(sc, ic->ic_curchan);
- /* update basic rate set */
- if (ic->ic_curmode == IEEE80211_MODE_11B) {
- /* 11b basic rates: 1, 2Mbps */
- RAL_WRITE(sc, RAL_ARSP_PLCP_1, 0x3);
- } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) {
- /* 11a basic rates: 6, 12, 24Mbps */
- RAL_WRITE(sc, RAL_ARSP_PLCP_1, 0x150);
- } else {
- /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */
- RAL_WRITE(sc, RAL_ARSP_PLCP_1, 0x15f);
- }
+ ni = ic->ic_bss;
- if (ic->ic_opmode != IEEE80211_M_MONITOR)
- ral_set_bssid(sc, ic->ic_bss->ni_bssid);
+ if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+ ral_update_plcp(sc);
+ ral_set_basicrates(sc);
+ ral_set_bssid(sc, ni->ni_bssid);
+ }
if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
ic->ic_opmode == IEEE80211_M_IBSS) {
- m = ieee80211_beacon_alloc(ic, ic->ic_bss, &sc->sc_bo);
+ m = ieee80211_beacon_alloc(ic, ni, &sc->sc_bo);
if (m == NULL) {
device_printf(sc->sc_dev,
"could not allocate beacon\n");
@@ -1035,8 +1029,8 @@ ral_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
break;
}
- ieee80211_ref_node(ic->ic_bss);
- error = ral_tx_bcn(sc, m, ic->ic_bss);
+ ieee80211_ref_node(ni);
+ error = ral_tx_bcn(sc, m, ni);
if (error != 0)
break;
}
@@ -1111,7 +1105,7 @@ ral_eeprom_read(struct ral_softc *sc, uint8_t addr)
RAL_EEPROM_CTL(sc, 0);
RAL_EEPROM_CTL(sc, RAL_EEPROM_C);
- return le16toh(val);
+ return val;
}
/*
@@ -1404,15 +1398,15 @@ ral_decryption_intr(struct ral_softc *sc)
uint32_t tsf_lo, tsf_hi;
/* get timestamp (low and high 32 bits) */
- tsf_lo = RAL_READ(sc, RAL_CSR16);
tsf_hi = RAL_READ(sc, RAL_CSR17);
+ tsf_lo = RAL_READ(sc, RAL_CSR16);
tap->wr_tsf =
htole64(((uint64_t)tsf_hi << 32) | tsf_lo);
tap->wr_flags = 0;
- tap->wr_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
- tap->wr_chan_flags =
- htole16(ic->ic_ibss_chan->ic_flags);
+ tap->wr_rate = ral_rxrate(desc);
+ tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
+ tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
tap->wr_antenna = sc->rx_ant;
tap->wr_antsignal = desc->rssi;
@@ -1584,9 +1578,41 @@ ral_intr(void *arg)
#define RAL_CTS_SIZE 14 /* 10 + 4(FCS) */
#define RAL_SIFS 10 /* us */
+
#define RAL_TXRX_TURNAROUND 10 /* us */
/*
+ * This function is only used by the Rx radiotap code.
+ */
+static uint8_t
+ral_rxrate(struct ral_rx_desc *desc)
+{
+ if (le32toh(desc->flags) & RAL_RX_OFDM) {
+ /* reverse function of ral_plcp_signal */
+ switch (desc->rate) {
+ case 0xb: return 12;
+ case 0xf: return 18;
+ case 0xa: return 24;
+ case 0xe: return 36;
+ case 0x9: return 48;
+ case 0xd: return 72;
+ case 0x8: return 96;
+ case 0xc: return 108;
+ }
+ } else {
+ if (desc->rate == 10)
+ return 2;
+ if (desc->rate == 20)
+ return 4;
+ if (desc->rate == 55)
+ return 11;
+ if (desc->rate == 110)
+ return 22;
+ }
+ return 2; /* should not get there */
+}
+
+/*
* Return the expected ack rate for a frame transmitted at rate `rate'.
* XXX: this should depend on the destination node basic rate set.
*/
@@ -1683,25 +1709,22 @@ ral_setup_tx_desc(struct ral_softc *sc, struct ral_tx_desc *desc,
desc->flags |= htole32(len << 16);
desc->flags |= encrypt ? htole32(RAL_TX_CIPHER_BUSY) :
htole32(RAL_TX_BUSY | RAL_TX_VALID);
- if (RAL_RATE_IS_OFDM(rate))
- desc->flags |= htole32(RAL_TX_OFDM);
desc->physaddr = htole32(physaddr);
- desc->wme = htole16(RAL_AIFSN(3) | RAL_LOGCWMIN(4) | RAL_LOGCWMAX(6));
+ desc->wme = htole16(RAL_AIFSN(2) | RAL_LOGCWMIN(3) | RAL_LOGCWMAX(8));
- /*
- * Fill PLCP fields.
- */
+ /* setup PLCP fields */
+ desc->plcp_signal = ral_plcp_signal(rate);
desc->plcp_service = 4;
- len += 4; /* account for FCS */
+ len += IEEE80211_CRC_LEN;
if (RAL_RATE_IS_OFDM(rate)) {
- /* IEEE Std 802.11a-1999, pp. 14 */
+ desc->flags |= htole32(RAL_TX_OFDM);
+
plcp_length = len & 0xfff;
desc->plcp_length_hi = plcp_length >> 6;
desc->plcp_length_lo = plcp_length & 0x3f;
} else {
- /* IEEE Std 802.11b-1999, pp. 16 */
plcp_length = (16 * len + rate - 1) / rate;
if (rate == 22) {
remainder = (16 * len) % 22;
@@ -1710,11 +1733,10 @@ ral_setup_tx_desc(struct ral_softc *sc, struct ral_tx_desc *desc,
}
desc->plcp_length_hi = plcp_length >> 8;
desc->plcp_length_lo = plcp_length & 0xff;
- }
- desc->plcp_signal = ral_plcp_signal(rate);
- if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
- desc->plcp_signal |= 0x08;
+ if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
+ desc->plcp_signal |= 0x08;
+ }
}
static int
@@ -1745,8 +1767,8 @@ ral_tx_bcn(struct ral_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
tap->wt_flags = 0;
tap->wt_rate = rate;
- tap->wt_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
+ tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
+ tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
tap->wt_antenna = sc->tx_ant;
bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
@@ -1801,8 +1823,8 @@ ral_tx_mgt(struct ral_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
tap->wt_flags = 0;
tap->wt_rate = rate;
- tap->wt_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
+ tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
+ tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
tap->wt_antenna = sc->tx_ant;
bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
@@ -1927,7 +1949,7 @@ ral_tx_data(struct ral_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
uint16_t dur;
int rtsrate, ackrate;
- rtsrate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 4;
+ rtsrate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
ackrate = ral_ack_rate(ic, rate);
dur = ral_txtime(m0->m_pkthdr.len + 4, rate, ic->ic_flags) +
@@ -2016,8 +2038,8 @@ ral_tx_data(struct ral_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
tap->wt_flags = 0;
tap->wt_rate = rate;
- tap->wt_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
+ tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
+ tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
tap->wt_antenna = sc->tx_ant;
bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
@@ -2291,7 +2313,6 @@ ral_rf_write(struct ral_softc *sc, uint8_t reg, uint32_t val)
static void
ral_set_chan(struct ral_softc *sc, struct ieee80211_channel *c)
{
-#define N(a) (sizeof (a) / sizeof ((a)[0]))
struct ieee80211com *ic = &sc->sc_ic;
uint8_t power, tmp;
u_int i, chan;
@@ -2359,16 +2380,12 @@ ral_set_chan(struct ral_softc *sc, struct ieee80211_channel *c)
/* dual-band RF */
case RAL_RF_5222:
- for (i = 0; i < N(ral_rf5222); i++)
- if (ral_rf5222[i].chan == chan)
- break;
+ for (i = 0; ral_rf5222[i].chan != chan; i++);
- if (i < N(ral_rf5222)) {
- ral_rf_write(sc, RAL_RF1, ral_rf5222[i].r1);
- ral_rf_write(sc, RAL_RF2, ral_rf5222[i].r2);
- ral_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
- ral_rf_write(sc, RAL_RF4, ral_rf5222[i].r4);
- }
+ ral_rf_write(sc, RAL_RF1, ral_rf5222[i].r1);
+ ral_rf_write(sc, RAL_RF2, ral_rf5222[i].r2);
+ ral_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
+ ral_rf_write(sc, RAL_RF4, ral_rf5222[i].r4);
break;
}
@@ -2385,7 +2402,6 @@ ral_set_chan(struct ral_softc *sc, struct ieee80211_channel *c)
/* clear CRC errors */
RAL_READ(sc, RAL_CNT0);
}
-#undef N
}
#if 0
@@ -2503,6 +2519,24 @@ ral_update_slot(struct ifnet *ifp)
}
static void
+ral_set_basicrates(struct ral_softc *sc)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+
+ /* update basic rate set */
+ if (ic->ic_curmode == IEEE80211_MODE_11B) {
+ /* 11b basic rates: 1, 2Mbps */
+ RAL_WRITE(sc, RAL_ARSP_PLCP_1, 0x3);
+ } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) {
+ /* 11a basic rates: 6, 12, 24Mbps */
+ RAL_WRITE(sc, RAL_ARSP_PLCP_1, 0x150);
+ } else {
+ /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */
+ RAL_WRITE(sc, RAL_ARSP_PLCP_1, 0x15f);
+ }
+}
+
+static void
ral_update_led(struct ral_softc *sc, int led1, int led2)
{
uint32_t tmp;
@@ -2755,8 +2789,6 @@ ral_init(void *priv)
}
/* set default BSS channel */
- ic->ic_bss->ni_chan = ic->ic_ibss_chan;
- ic->ic_curchan = ic->ic_ibss_chan;
ral_set_chan(sc, ic->ic_curchan);
/* kick Rx */
diff --git a/sys/dev/ral/if_ralreg.h b/sys/dev/ral/if_ralreg.h
index 6887901819f1..c544e696160b 100644
--- a/sys/dev/ral/if_ralreg.h
+++ b/sys/dev/ral/if_ralreg.h
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*-
- * Copyright (c) 2005
+ * Copyright (c) 2005, 2006
* Damien Bergamini <damien.bergamini@free.fr>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -230,6 +230,7 @@ struct ral_rx_desc {
uint32_t flags;
#define RAL_RX_BUSY (1 << 0)
#define RAL_RX_CRC_ERROR (1 << 5)
+#define RAL_RX_OFDM (1 << 6)
#define RAL_RX_PHY_ERROR (1 << 7)
#define RAL_RX_CIPHER_BUSY (1 << 8)
#define RAL_RX_ICV_ERROR (1 << 9)
diff --git a/sys/dev/ral/if_ralvar.h b/sys/dev/ral/if_ralvar.h
index 9bf024cf0ac8..c7d7501dd6e7 100644
--- a/sys/dev/ral/if_ralvar.h
+++ b/sys/dev/ral/if_ralvar.h
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*-
- * Copyright (c) 2005
+ * Copyright (c) 2005, 2006
* Damien Bergamini <damien.bergamini@free.fr>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -21,6 +21,7 @@ struct ral_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
uint64_t wr_tsf;
uint8_t wr_flags;
+ uint8_t wr_rate;
uint16_t wr_chan_freq;
uint16_t wr_chan_flags;
uint8_t wr_antenna;
@@ -30,6 +31,7 @@ struct ral_rx_radiotap_header {
#define RAL_RX_RADIOTAP_PRESENT \
((1 << IEEE80211_RADIOTAP_TSFT) | \
(1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))