From owner-svn-src-all@freebsd.org Thu May 5 07:04:40 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 279EAB2EF56; Thu, 5 May 2016 07:04:40 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0440C1037; Thu, 5 May 2016 07:04:39 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u4574dfm010097; Thu, 5 May 2016 07:04:39 GMT (envelope-from adrian@FreeBSD.org) Received: (from adrian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u4574dRG010095; Thu, 5 May 2016 07:04:39 GMT (envelope-from adrian@FreeBSD.org) Message-Id: <201605050704.u4574dRG010095@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: adrian set sender to adrian@FreeBSD.org using -f From: Adrian Chadd Date: Thu, 5 May 2016 07:04:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r299110 - head/sys/dev/bwn X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 May 2016 07:04:40 -0000 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;