[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..)
This commit is contained in:
parent
1f0b67157f
commit
2997dc482e
@ -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 mbuf *m, const void *_rxhdr)
|
||||
|
||||
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 mbuf *m, const void *_rxhdr)
|
||||
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 mbuf *m, const void *_rxhdr)
|
||||
}
|
||||
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);
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user