summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2008-02-16 16:45:29 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2008-02-16 16:45:29 +0000
commit41c8aef51b021f36dbdfca89817950243335c697 (patch)
tree665c3b17c76a63b7e164713ced704f5bc09113a5 /sys
parentea029ac8bd4434a4b7d5808af29cc9bbc8acde64 (diff)
Report rssi and rate in rx radio tap.
From the DragonFlyBSD driver.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ic/bwi.c170
-rw-r--r--sys/dev/ic/bwivar.h17
2 files changed, 179 insertions, 8 deletions
diff --git a/sys/dev/ic/bwi.c b/sys/dev/ic/bwi.c
index f935cb51d88..b2d8e73fdef 100644
--- a/sys/dev/ic/bwi.c
+++ b/sys/dev/ic/bwi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bwi.c,v 1.66 2008/02/16 14:56:00 mglocker Exp $ */
+/* $OpenBSD: bwi.c,v 1.67 2008/02/16 16:45:28 mglocker Exp $ */
/*
* Copyright (c) 2007 The DragonFly Project. All rights reserved.
@@ -245,6 +245,12 @@ void bwi_rf_on_11bg(struct bwi_mac *);
void bwi_rf_set_ant_mode(struct bwi_mac *, int);
int bwi_rf_get_latest_tssi(struct bwi_mac *, int8_t[], uint16_t);
int bwi_rf_tssi2dbm(struct bwi_mac *, int8_t, int8_t *);
+int bwi_rf_calc_rssi_bcm2050(struct bwi_mac *,
+ const struct bwi_rxbuf_hdr *);
+int bwi_rf_calc_rssi_bcm2053(struct bwi_mac *,
+ const struct bwi_rxbuf_hdr *);
+int bwi_rf_calc_rssi_bcm2060(struct bwi_mac *,
+ const struct bwi_rxbuf_hdr *);
uint16_t bwi_rf_lo_measure_11b(struct bwi_mac *);
void bwi_rf_lo_update_11b(struct bwi_mac *);
@@ -353,6 +359,8 @@ void bwi_regwin_disable(struct bwi_softc *, struct bwi_regwin *,
void bwi_set_bssid(struct bwi_softc *, const uint8_t *);
void bwi_updateslot(struct ieee80211com *);
void bwi_calibrate(void *);
+int bwi_calc_rssi(struct bwi_softc *,
+ const struct bwi_rxbuf_hdr *);
uint8_t bwi_ack_rate(struct ieee80211_node *, uint8_t);
uint16_t bwi_txtime(struct ieee80211com *, struct ieee80211_node *,
uint, uint8_t, uint32_t);
@@ -3769,12 +3777,15 @@ bwi_rf_attach(struct bwi_mac *mac)
rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11A;
rf->rf_on = bwi_rf_on_11a;
rf->rf_off = bwi_rf_off_11a;
+ rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2060;
break;
case IEEE80211_MODE_11B:
if (type == BWI_RF_T_BCM2050) {
rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG;
+ rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050;
} else if (type == BWI_RF_T_BCM2053) {
rf->rf_ctrl_adj = 1;
+ rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2053;
} else {
DPRINTF(1, "%s: only BCM2050/BCM2053 RF is supported "
"for supported for 11B PHY\n", sc->sc_dev.dv_xname);
@@ -3803,6 +3814,7 @@ bwi_rf_attach(struct bwi_mac *mac)
rf->rf_off = bwi_rf_off_11bg;
rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11g;
rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11g;
+ rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050;
rf->rf_lo_update = bwi_rf_lo_update_11g;
break;
default:
@@ -5874,6 +5886,141 @@ bwi_rf_tssi2dbm(struct bwi_mac *mac, int8_t tssi, int8_t *txpwr)
return (0);
}
+int
+bwi_rf_calc_rssi_bcm2050(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
+{
+ uint16_t flags1, flags3;
+ int rssi, lna_gain;
+
+ rssi = hdr->rxh_rssi;
+ flags1 = letoh16(hdr->rxh_flags1);
+ flags3 = letoh16(hdr->rxh_flags3);
+
+#define NEW_BCM2050_RSSI
+#ifdef NEW_BCM2050_RSSI
+ if (flags1 & BWI_RXH_F1_OFDM) {
+ if (rssi > 127)
+ rssi -= 256;
+ if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
+ rssi += 17;
+ else
+ rssi -= 4;
+ return (rssi);
+ }
+
+ if (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
+ struct bwi_rf *rf = &mac->mac_rf;
+
+ if (rssi >= BWI_NRSSI_TBLSZ)
+ rssi = BWI_NRSSI_TBLSZ - 1;
+
+ rssi = ((31 - (int)rf->rf_nrssi_table[rssi]) * -131) / 128;
+ rssi -= 67;
+ } else {
+ rssi = ((31 - rssi) * -149) / 128;
+ rssi -= 68;
+ }
+
+ if (mac->mac_phy.phy_mode != IEEE80211_MODE_11G)
+ return (rssi);
+
+ if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
+ rssi += 20;
+
+ lna_gain = __SHIFTOUT(letoh16(hdr->rxh_phyinfo),
+ BWI_RXH_PHYINFO_LNAGAIN);
+ DPRINTF(mac->mac_sc, BWI_DBG_RF | BWI_DBG_RX,
+ "lna_gain %d, phyinfo 0x%04x\n",
+ lna_gain, le16toh(hdr->rxh_phyinfo));
+ switch (lna_gain) {
+ case 0:
+ rssi += 27;
+ break;
+ case 1:
+ rssi += 6;
+ break;
+ case 2:
+ rssi += 12;
+ break;
+ case 3:
+ /*
+ * XXX
+ * According to v3 spec, we should do _nothing_ here,
+ * but it seems that the result RSSI will be too low
+ * (relative to what ath(4) says). Raise it a little
+ * bit.
+ */
+ rssi += 5;
+ break;
+ default:
+ panic("impossible lna gain %d", lna_gain);
+ }
+#else /* !NEW_BCM2050_RSSI */
+ lna_gain = 0; /* shut up gcc warning */
+
+ if (flags1 & BWI_RXH_F1_OFDM) {
+ if (rssi > 127)
+ rssi -= 256;
+ rssi = (rssi * 73) / 64;
+
+ if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
+ rssi += 25;
+ else
+ rssi -= 3;
+ return (rssi);
+ }
+
+ if (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
+ struct bwi_rf *rf = &mac->mac_rf;
+
+ if (rssi >= BWI_NRSSI_TBLSZ)
+ rssi = BWI_NRSSI_TBLSZ - 1;
+
+ rssi = ((31 - (int)rf->rf_nrssi_table[rssi]) * -131) / 128;
+ rssi -= 57;
+ } else {
+ rssi = ((31 - rssi) * -149) / 128;
+ rssi -= 68;
+ }
+
+ if (mac->mac_phy.phy_mode != IEEE80211_MODE_11G)
+ return (rssi);
+
+ if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
+ rssi += 25;
+#endif /* NEW_BCM2050_RSSI */
+ return (rssi);
+}
+
+int
+bwi_rf_calc_rssi_bcm2053(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
+{
+ uint16_t flags1;
+ int rssi;
+
+ rssi = (((int)hdr->rxh_rssi - 11) * 103) / 64;
+
+ flags1 = letoh16(hdr->rxh_flags1);
+ if (flags1 & BWI_RXH_F1_BCM2053_RSSI)
+ rssi -= 109;
+ else
+ rssi -= 83;
+
+ return (rssi);
+}
+
+int
+bwi_rf_calc_rssi_bcm2060(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
+{
+ int rssi;
+
+ rssi = hdr->rxh_rssi;
+ if (rssi > 127)
+ rssi -= 256;
+
+ return (rssi);
+}
+
uint16_t
bwi_rf_lo_measure_11b(struct bwi_mac *mac)
{
@@ -8006,7 +8153,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
struct mbuf *m;
void *plcp;
uint16_t flags2;
- int buflen, wh_ofs, hdr_extra, type, rate;
+ int buflen, wh_ofs, hdr_extra, rssi, type, rate;
m = rb->rb_mbuf;
bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0,
@@ -8035,6 +8182,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
}
plcp = ((uint8_t *)(hdr + 1) + hdr_extra);
+ rssi = bwi_calc_rssi(sc, hdr);
m->m_pkthdr.rcvif = ifp;
m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr);
@@ -8051,16 +8199,15 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
struct mbuf mb;
struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtap;
- /* TODO: calculate rate and signal */
tap->wr_tsf = hdr->rxh_tsf;
tap->wr_flags = 0;
- tap->wr_rate = 0;
+ tap->wr_rate = rate;
tap->wr_chan_freq =
htole16(ic->ic_bss->ni_chan->ic_freq);
tap->wr_chan_flags =
htole16(ic->ic_bss->ni_chan->ic_flags);
- tap->wr_antsignal = 0;
- tap->wr_antnoise = 0;
+ tap->wr_antsignal = rssi;
+ tap->wr_antnoise = BWI_NOISE_FLOOR;
mb.m_data = (caddr_t)tap;
mb.m_len = sc->sc_rxtap_len;
@@ -9181,3 +9328,14 @@ bwi_calibrate(void *xsc)
splx(s);
}
+
+int
+bwi_calc_rssi(struct bwi_softc *sc, const struct bwi_rxbuf_hdr *hdr)
+{
+ struct bwi_mac *mac;
+
+ KKASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC);
+ mac = (struct bwi_mac *)sc->sc_cur_regwin;
+
+ return (bwi_rf_calc_rssi(mac, hdr));
+}
diff --git a/sys/dev/ic/bwivar.h b/sys/dev/ic/bwivar.h
index 5f248c036ff..60b3c3100bf 100644
--- a/sys/dev/ic/bwivar.h
+++ b/sys/dev/ic/bwivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bwivar.h,v 1.21 2008/02/16 14:56:00 mglocker Exp $ */
+/* $OpenBSD: bwivar.h,v 1.22 2008/02/16 16:45:28 mglocker Exp $ */
/*
* Copyright (c) 2007 The DragonFly Project. All rights reserved.
@@ -63,6 +63,8 @@
#define BWI_LED_EVENT_RX 2
#define BWI_LED_SLOWDOWN(dur) (dur) = (((dur) * 3) / 2)
+#define BWI_NOISE_FLOOR -95 /* TODO: noise floor calc */
+
#define CSR_READ_4(sc, reg) \
bus_space_read_4((sc)->sc_mem_bt, (sc)->sc_mem_bh, (reg))
#define CSR_READ_2(sc, reg) \
@@ -120,17 +122,22 @@ struct bwi_rxbuf_hdr {
uint16_t rxh_flags1;
uint8_t rxh_rssi;
uint8_t rxh_sq;
- uint8_t rxh_pad2[2];
+ uint16_t rxh_phyinfo; /* BWI_RXH_PHYINFO_ */
uint16_t rxh_flags3;
uint16_t rxh_flags2; /* BWI_RXH_F2_ */
uint16_t rxh_tsf;
uint8_t rxh_pad3[14]; /* Padded to 30bytes */
} __packed;
+#define BWI_RXH_F1_BCM2053_RSSI (1 << 14)
#define BWI_RXH_F1_OFDM (1 << 0)
#define BWI_RXH_F2_TYPE2FRAME (1 << 2)
+#define BWI_RXH_F3_BCM2050_RSSI (1 << 10)
+
+#define BWI_RXH_PHYINFO_LNAGAIN (3 << 14)
+
struct bwi_txbuf_hdr {
/* Little endian */
uint32_t txh_mac_ctrl; /* BWI_TXH_MAC_C_ */
@@ -704,6 +711,12 @@ bwi_rf_set_nrssi_thr(struct bwi_mac *_mac)
_mac->mac_rf.rf_set_nrssi_thr(_mac);
}
+static __inline int
+bwi_rf_calc_rssi(struct bwi_mac *_mac, const struct bwi_rxbuf_hdr *_hdr)
+{
+ return (_mac->mac_rf.rf_calc_rssi(_mac, _hdr));
+}
+
static __inline void
bwi_rf_lo_update(struct bwi_mac *_mac)
{