svn commit: r299110 - head/sys/dev/bwn
Adrian Chadd
adrian at FreeBSD.org
Thu May 5 07:04:40 UTC 2016
Author: adrian
Date: Thu May 5 07:04:38 2016
New Revision: 299110
URL: https://svnweb.freebsd.org/changeset/base/299110
Log:
[bwn] implement firmware tx/rx versioning and fix RSSI calculation.
Different versions of firmware have different requirments for TX/RX
packet layouts (and other things, of course.) Currently the driver
checks between 3xx and 4xx firmware by using the BWN_ISOLDFMT() macro,
which doesn't take into account the 5xx firmware (which I think I need
for the HT and N series PHY chips. I'll know when I do the port.)
BWN_HDRSIZE() also needs to learn about the 5xx series firmware
as well.
So:
* add a firmware version enum
* populate it based on the firmware version we read at load time
* don't finish loading if the firmware is the 5xx firmware; any
code using BWN_ISOLDFMT or BWN_HDRSIZE needs updating (most notably
the TX and RX bits.)
Then, for RX RSSI:
* write down and reimplement the b43 rssi calculation method;
* use it for the correct PHYs (which are all the ones we support);
* do the RSSI calculation before radiotap, not after.
Tested:
* Broadcom BCM4312, STA mode
Obtained from: Linux b43 (careful writing and reimplementing; lots of integer math..)
Modified:
head/sys/dev/bwn/if_bwn.c
head/sys/dev/bwn/if_bwnvar.h
Modified: head/sys/dev/bwn/if_bwn.c
==============================================================================
--- head/sys/dev/bwn/if_bwn.c Thu May 5 06:58:30 2016 (r299109)
+++ head/sys/dev/bwn/if_bwn.c Thu May 5 07:04:38 2016 (r299110)
@@ -3987,6 +3987,33 @@ bwn_fw_loaducode(struct bwn_mac *mac)
error = EOPNOTSUPP;
goto error;
}
+
+ /*
+ * Determine firmware header version; needed for TX/RX packet
+ * handling.
+ */
+ if (mac->mac_fw.rev >= 598)
+ mac->mac_fw.fw_hdr_format = BWN_FW_HDR_598;
+ else if (mac->mac_fw.rev >= 410)
+ mac->mac_fw.fw_hdr_format = BWN_FW_HDR_410;
+ else
+ mac->mac_fw.fw_hdr_format = BWN_FW_HDR_351;
+
+ /*
+ * We don't support rev 598 or later; that requires
+ * another round of changes to the TX/RX descriptor
+ * and status layout.
+ *
+ * So, complain this is the case and exit out, rather
+ * than attaching and then failing.
+ */
+ if (mac->mac_fw.fw_hdr_format == BWN_FW_HDR_598) {
+ device_printf(sc->sc_dev,
+ "firmware is too new (>=598); not supported\n");
+ error = EOPNOTSUPP;
+ goto error;
+ }
+
mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
BWN_SHARED_UCODE_PATCH);
date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
@@ -5401,6 +5428,63 @@ bwn_hwrate2ieeerate(int rate)
}
}
+/*
+ * Post process the RX provided RSSI.
+ *
+ * Valid for A, B, G, LP PHYs.
+ */
+static int8_t
+bwn_rx_rssi_calc(struct bwn_mac *mac, int8_t in_rssi,
+ int ofdm, int adjust_2053, int adjust_2050)
+{
+ struct bwn_phy *phy = &mac->mac_phy;
+ struct bwn_phy_g *gphy = &phy->phy_g;
+ int tmp;
+
+ switch (phy->rf_ver) {
+ case 0x2050:
+ if (ofdm) {
+ tmp = in_rssi;
+ if (tmp > 127)
+ tmp -= 256;
+ tmp = tmp * 73 / 64;
+ if (adjust_2050)
+ tmp += 25;
+ else
+ tmp -= 3;
+ } else {
+ if (siba_sprom_get_bf_lo(mac->mac_sc->sc_dev)
+ & BWN_BFL_RSSI) {
+ if (in_rssi > 63)
+ in_rssi = 63;
+ tmp = gphy->pg_nrssi_lt[in_rssi];
+ tmp = (31 - tmp) * -131 / 128 - 57;
+ } else {
+ tmp = in_rssi;
+ tmp = (31 - tmp) * -149 / 128 - 68;
+ }
+ if (phy->type == BWN_PHYTYPE_G && adjust_2050)
+ tmp += 25;
+ }
+ break;
+ case 0x2060:
+ if (in_rssi > 127)
+ tmp = in_rssi - 256;
+ else
+ tmp = in_rssi;
+ break;
+ default:
+ tmp = in_rssi;
+ tmp = (tmp - 11) * 103 / 64;
+ if (adjust_2053)
+ tmp -= 109;
+ else
+ tmp -= 83;
+ }
+
+ return (tmp);
+}
+
static void
bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
{
@@ -5420,8 +5504,11 @@ bwn_rxeof(struct bwn_mac *mac, struct mb
phystat0 = le16toh(rxhdr->phy_status0);
phystat3 = le16toh(rxhdr->phy_status3);
+
+ /* XXX Note: mactime, macstat, chanstat need fixing for fw 598 */
macstat = le32toh(rxhdr->mac_status);
chanstat = le16toh(rxhdr->channel);
+
phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
if (macstat & BWN_RX_MAC_FCSERR)
@@ -5452,8 +5539,6 @@ bwn_rxeof(struct bwn_mac *mac, struct mb
BWN_ISOLDFMT(mac),
(macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
- /* XXX calculating RSSI & noise & antenna */
-
if (phystat0 & BWN_RX_PHYST0_OFDM)
rate = bwn_plcp_get_ofdmrate(mac, plcp,
phytype == BWN_PHYTYPE_A);
@@ -5465,14 +5550,29 @@ bwn_rxeof(struct bwn_mac *mac, struct mb
}
sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
+ /* rssi/noise */
+ switch (phytype) {
+ case BWN_PHYTYPE_A:
+ case BWN_PHYTYPE_B:
+ case BWN_PHYTYPE_G:
+ case BWN_PHYTYPE_LP:
+ rssi = bwn_rx_rssi_calc(mac, rxhdr->phy.abg.rssi,
+ !! (phystat0 & BWN_RX_PHYST0_OFDM),
+ !! (phystat0 & BWN_RX_PHYST0_GAINCTL),
+ !! (phystat3 & BWN_RX_PHYST3_TRSTATE));
+ break;
+ default:
+ /* XXX TODO: implement rssi for other PHYs */
+ break;
+ }
+
+ noise = mac->mac_stats.link_noise;
+
/* RX radio tap */
if (ieee80211_radiotap_active(ic))
bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
m_adj(m, -IEEE80211_CRC_LEN);
- rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */
- noise = mac->mac_stats.link_noise;
-
BWN_UNLOCK(sc);
ni = ieee80211_find_rxnode(ic, wh);
Modified: head/sys/dev/bwn/if_bwnvar.h
==============================================================================
--- head/sys/dev/bwn/if_bwnvar.h Thu May 5 06:58:30 2016 (r299109)
+++ head/sys/dev/bwn/if_bwnvar.h Thu May 5 07:04:38 2016 (r299110)
@@ -751,6 +751,12 @@ struct bwn_fwinitvals {
} __packed data;
} __packed;
+enum bwn_fw_hdr_format {
+ BWN_FW_HDR_598,
+ BWN_FW_HDR_410,
+ BWN_FW_HDR_351,
+};
+
enum bwn_fwtype {
BWN_FWTYPE_DEFAULT,
BWN_FWTYPE_OPENSOURCE,
@@ -773,6 +779,7 @@ struct bwn_fw {
struct bwn_fwfile pcm;
struct bwn_fwfile initvals;
struct bwn_fwfile initvals_band;
+ enum bwn_fw_hdr_format fw_hdr_format;
uint16_t rev;
uint16_t patch;
More information about the svn-src-all
mailing list