From 641ea7854aab1d7d809fea05c73a9f353240e12a Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Sat, 15 Sep 2007 09:59:29 +0000 Subject: [PATCH] Convert RSSI into signal strength (relative to noise floor) --- sys/dev/netif/bwi/bwirf.c | 147 +++++++++++++++++++++++++++++++++- sys/dev/netif/bwi/bwirf.h | 8 +- sys/dev/netif/bwi/if_bwi.c | 21 +++-- sys/dev/netif/bwi/if_bwivar.h | 20 ++++- 4 files changed, 185 insertions(+), 11 deletions(-) diff --git a/sys/dev/netif/bwi/bwirf.c b/sys/dev/netif/bwi/bwirf.c index abecc60376..c0fa5110d6 100644 --- a/sys/dev/netif/bwi/bwirf.c +++ b/sys/dev/netif/bwi/bwirf.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/dev/netif/bwi/bwirf.c,v 1.1 2007/09/08 06:15:54 sephe Exp $ + * $DragonFly: src/sys/dev/netif/bwi/bwirf.c,v 1.2 2007/09/15 09:59:29 sephe Exp $ */ #include @@ -115,6 +115,13 @@ static void bwi_rf_set_nrssi_thr_11g(struct bwi_mac *); static void bwi_rf_init_sw_nrssi_table(struct bwi_mac *); +static int bwi_rf_calc_rssi_bcm2050(struct bwi_mac *, + const struct bwi_rxbuf_hdr *); +static int bwi_rf_calc_rssi_bcm2053(struct bwi_mac *, + const struct bwi_rxbuf_hdr *); +static int bwi_rf_calc_rssi_bcm2060(struct bwi_mac *, + const struct bwi_rxbuf_hdr *); + static void bwi_rf_on_11a(struct bwi_mac *); static void bwi_rf_on_11bg(struct bwi_mac *); @@ -250,12 +257,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 { device_printf(sc->sc_dev, "only BCM2050/BCM2053 RF " "is supported for 11B PHY\n"); @@ -280,6 +290,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; break; default: device_printf(sc->sc_dev, "unsupported PHY mode\n"); @@ -2341,3 +2352,137 @@ bwi_rf_tssi2dbm(struct bwi_mac *mac, int8_t tssi, int8_t *txpwr) *txpwr = rf->rf_txpower_map[pwr_idx]; return 0; } + +static 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 = le16toh(hdr->rxh_flags1); + flags3 = le16toh(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(le16toh(hdr->rxh_phyinfo), + BWI_RXH_PHYINFO_LNAGAIN); +#if 0 + DPRINTF(mac->mac_sc, "lna_gain %d, phyinfo 0x%04x\n", + lna_gain, le16toh(hdr->rxh_phyinfo)); +#endif + 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; +} + +static 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 = le16toh(hdr->rxh_flags1); + if (flags1 & BWI_RXH_F1_BCM2053_RSSI) + rssi -= 109; + else + rssi -= 83; + return rssi; +} + +static 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; +} diff --git a/sys/dev/netif/bwi/bwirf.h b/sys/dev/netif/bwi/bwirf.h index f371bed47a..bbf8c5512a 100644 --- a/sys/dev/netif/bwi/bwirf.h +++ b/sys/dev/netif/bwi/bwirf.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/dev/netif/bwi/bwirf.h,v 1.1 2007/09/08 06:15:54 sephe Exp $ + * $DragonFly: src/sys/dev/netif/bwi/bwirf.h,v 1.2 2007/09/15 09:59:29 sephe Exp $ */ #ifndef _BWI_RF_H @@ -90,6 +90,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); +} + #define RF_WRITE(mac, ofs, val) bwi_rf_write((mac), (ofs), (val)) #define RF_READ(mac, ofs) bwi_rf_read((mac), (ofs)) diff --git a/sys/dev/netif/bwi/if_bwi.c b/sys/dev/netif/bwi/if_bwi.c index 08a17cecfc..8e889e57f4 100644 --- a/sys/dev/netif/bwi/if_bwi.c +++ b/sys/dev/netif/bwi/if_bwi.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/dev/netif/bwi/if_bwi.c,v 1.1 2007/09/08 06:15:54 sephe Exp $ + * $DragonFly: src/sys/dev/netif/bwi/if_bwi.c,v 1.2 2007/09/15 09:59:29 sephe Exp $ */ #include @@ -134,6 +134,7 @@ static void bwi_txeof(struct bwi_softc *); static void bwi_txeof_status(struct bwi_softc *, int); static void bwi_enable_intrs(struct bwi_softc *, uint32_t); static void bwi_disable_intrs(struct bwi_softc *, uint32_t); +static int bwi_calc_rssi(struct bwi_softc *, const struct bwi_rxbuf_hdr *); static int bwi_dma_alloc(struct bwi_softc *); static void bwi_dma_free(struct bwi_softc *); @@ -2455,7 +2456,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx) struct mbuf *m; uint8_t plcp_signal; uint16_t flags2; - int buflen, wh_ofs, hdr_extra; + int buflen, wh_ofs, hdr_extra, rssi; m = rb->rb_mbuf; bus_dmamap_sync(sc->sc_buf_dtag, rb->rb_dmap, @@ -2484,6 +2485,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx) } plcp_signal = *((uint8_t *)(hdr + 1) + hdr_extra); + rssi = bwi_calc_rssi(sc, hdr) - BWI_NOISE_FLOOR; m->m_pkthdr.rcvif = ifp; m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr); @@ -2496,9 +2498,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx) wh = mtod(m, struct ieee80211_frame_min *); ni = ieee80211_find_rxnode(ic, wh); - ieee80211_input(ic, m, ni, hdr->rxh_rssi, - le16toh(hdr->rxh_tsf)); - + ieee80211_input(ic, m, ni, rssi, le16toh(hdr->rxh_tsf)); ieee80211_free_node(ni); next: idx = (idx + 1) % BWI_RX_NDESC; @@ -3390,3 +3390,14 @@ bwi_calibrate(void *xsc) lwkt_serialize_exit(ifp->if_serializer); } + +static 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/netif/bwi/if_bwivar.h b/sys/dev/netif/bwi/if_bwivar.h index 57e3f6a962..e19351c485 100644 --- a/sys/dev/netif/bwi/if_bwivar.h +++ b/sys/dev/netif/bwi/if_bwivar.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/dev/netif/bwi/if_bwivar.h,v 1.1 2007/09/08 06:15:54 sephe Exp $ + * $DragonFly: src/sys/dev/netif/bwi/if_bwivar.h,v 1.2 2007/09/15 09:59:29 sephe Exp $ */ #ifndef _IF_BWIVAR_H @@ -55,6 +55,8 @@ #define BWI_SHRETRY_FB 3 #define BWI_LGRETRY_FB 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) \ @@ -116,18 +118,25 @@ struct bwi_rxbuf_hdr { /* Little endian */ uint16_t rxh_buflen; /* exclude bwi_rxbuf_hdr */ uint8_t rxh_pad1[2]; - uint16_t rxh_flags1; + uint16_t rxh_flags1; /* BWI_RXH_F1_ */ uint8_t rxh_rssi; uint8_t rxh_sq; - uint8_t rxh_pad2[2]; - uint16_t rxh_flags3; + uint16_t rxh_phyinfo; /* BWI_RXH_PHYINFO_ */ + uint16_t rxh_flags3; /* BWI_RXH_F3_ */ 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 __BIT(14) +#define BWI_RXH_F1_OFDM __BIT(0) + #define BWI_RXH_F2_TYPE2FRAME __BIT(2) +#define BWI_RXH_F3_BCM2050_RSSI __BIT(10) + +#define BWI_RXH_PHYINFO_LNAGAIN __BITS(15, 14) + struct bwi_txbuf_hdr { /* Little endian */ uint32_t txh_mac_ctrl; /* BWI_TXH_MAC_C_ */ @@ -361,6 +370,9 @@ struct bwi_rf { void (*rf_set_nrssi_thr)(struct bwi_mac *); void (*rf_calc_nrssi_slope)(struct bwi_mac *); + int (*rf_calc_rssi) + (struct bwi_mac *, + const struct bwi_rxbuf_hdr *); #define BWI_TSSI_MAX 64 int8_t rf_txpower_map0[BWI_TSSI_MAX]; -- 2.41.0