svn commit: r300114 - head/sys/dev/bwn
Adrian Chadd
adrian at FreeBSD.org
Wed May 18 05:56:26 UTC 2016
Author: adrian
Date: Wed May 18 05:56:25 2016
New Revision: 300114
URL: https://svnweb.freebsd.org/changeset/base/300114
Log:
[bwn] add initial 5xx firmware API support
* Add the new TX/RX frame formats;
* Use the right TX/RX format based on the frame info;
* Disable the 5xx firmware check, since now it should
somewhat work (but note, we don't yet use it unless
you manually add ucode11/initvals11 from the 5.x driver
to bwn-kmod-firmware;
* Misc: update some comments/debugging now I know what's
actually going on.
Tested:
* BCM4321MC, STA mode, both 4xx and 666 firmware, DMA mode
TODO:
* The newer firmware ends up logging "warn: firmware state (0)";
not sure yet what's going on there. But, yes, it still works.
I'm committing this via a BCM4321MC, 11a station, firmware
rev 666.
Obtained from: Linux b43 (TX/RX descriptor format for 5xx)
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 Wed May 18 04:35:58 2016 (r300113)
+++ head/sys/dev/bwn/if_bwn.c Wed May 18 05:56:25 2016 (r300114)
@@ -1216,14 +1216,12 @@ bwn_attach_core(struct bwn_mac *mac)
}
/*
- * XXX turns off PHY A because it's not supported.
- * Implement PHY-A support so we can use it for PHY-G
- * dual-band support.
+ * XXX The PHY-G support doesn't do 5GHz operation.
*/
if (mac->mac_phy.type != BWN_PHYTYPE_LP &&
mac->mac_phy.type != BWN_PHYTYPE_N) {
device_printf(sc->sc_dev,
- "%s: forcing 2GHz only; missing PHY-A support\n",
+ "%s: forcing 2GHz only; no dual-band support for PHY\n",
__func__);
have_a = 0;
have_bg = 1;
@@ -3791,6 +3789,8 @@ bwn_psctl(struct bwn_mac *mac, uint32_t
DELAY(10);
}
}
+ DPRINTF(mac->mac_sc, BWN_DEBUG_RESET, "%s: ucstat=%d\n", __func__,
+ ucstat);
}
static int
@@ -4186,12 +4186,14 @@ bwn_fw_loaducode(struct bwn_mac *mac)
* So, complain this is the case and exit out, rather
* than attaching and then failing.
*/
+#if 0
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;
}
+#endif
mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
BWN_SHARED_UCODE_PATCH);
@@ -5351,7 +5353,17 @@ bwn_dma_rxeof(struct bwn_dma_ring *dr, i
len, dr->dr_rx_bufsize, cnt);
return;
}
- macstat = le32toh(rxhdr->mac_status);
+
+ switch (mac->mac_fw.fw_hdr_format) {
+ case BWN_FW_HDR_351:
+ case BWN_FW_HDR_410:
+ macstat = le32toh(rxhdr->ps4.r351.mac_status);
+ break;
+ case BWN_FW_HDR_598:
+ macstat = le32toh(rxhdr->ps4.r598.mac_status);
+ break;
+ }
+
if (macstat & BWN_RX_MAC_FCSERR) {
if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
device_printf(sc->sc_dev, "RX drop\n");
@@ -5452,7 +5464,16 @@ ready:
goto error;
}
- macstat = le32toh(rxhdr.mac_status);
+ switch (mac->mac_fw.fw_hdr_format) {
+ case BWN_FW_HDR_351:
+ case BWN_FW_HDR_410:
+ macstat = le32toh(rxhdr.ps4.r351.mac_status);
+ break;
+ case BWN_FW_HDR_598:
+ macstat = le32toh(rxhdr.ps4.r598.mac_status);
+ break;
+ }
+
if (macstat & BWN_RX_MAC_FCSERR) {
if (!(mac->mac_sc->sc_filters & BWN_MACCTL_PASS_BADFCS)) {
device_printf(sc->sc_dev, "%s: FCS error", __func__);
@@ -5706,11 +5727,25 @@ bwn_rxeof(struct bwn_mac *mac, struct mb
BWN_ASSERT_LOCKED(sc);
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);
+ /*
+ * XXX Note: phy_status3 doesn't exist for HT-PHY; it's only
+ * used for LP-PHY.
+ */
+ phystat3 = le16toh(rxhdr->ps3.lp.phy_status3);
+
+ switch (mac->mac_fw.fw_hdr_format) {
+ case BWN_FW_HDR_351:
+ case BWN_FW_HDR_410:
+ macstat = le32toh(rxhdr->ps4.r351.mac_status);
+ chanstat = le16toh(rxhdr->ps4.r351.channel);
+ break;
+ case BWN_FW_HDR_598:
+ macstat = le32toh(rxhdr->ps4.r598.mac_status);
+ chanstat = le16toh(rxhdr->ps4.r598.channel);
+ break;
+ }
+
phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
@@ -6181,10 +6216,22 @@ bwn_set_txhdr(struct bwn_mac *mac, struc
m->m_pkthdr.len, rate, isshort);
/* XXX TX encryption */
- bwn_plcp_genhdr(BWN_ISOLDFMT(mac) ?
- (struct bwn_plcp4 *)(&txhdr->body.old.plcp) :
- (struct bwn_plcp4 *)(&txhdr->body.new.plcp),
- m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
+
+ switch (mac->mac_fw.fw_hdr_format) {
+ case BWN_FW_HDR_351:
+ bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->body.r351.plcp),
+ m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
+ break;
+ case BWN_FW_HDR_410:
+ bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->body.r410.plcp),
+ m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
+ break;
+ case BWN_FW_HDR_598:
+ bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->body.r598.plcp),
+ m->m_pkthdr.len + IEEE80211_CRC_LEN, rate);
+ break;
+ }
+
bwn_plcp_genhdr((struct bwn_plcp4 *)(&txhdr->plcp_fb),
m->m_pkthdr.len + IEEE80211_CRC_LEN, rate_fb);
@@ -6243,9 +6290,22 @@ bwn_set_txhdr(struct bwn_mac *mac, struc
+ ieee80211_ack_duration(ic->ic_rt, rate, isshort);
if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
- cts = (struct ieee80211_frame_cts *)(BWN_ISOLDFMT(mac) ?
- (txhdr->body.old.rts_frame) :
- (txhdr->body.new.rts_frame));
+
+ switch (mac->mac_fw.fw_hdr_format) {
+ case BWN_FW_HDR_351:
+ cts = (struct ieee80211_frame_cts *)
+ txhdr->body.r351.rts_frame;
+ break;
+ case BWN_FW_HDR_410:
+ cts = (struct ieee80211_frame_cts *)
+ txhdr->body.r410.rts_frame;
+ break;
+ case BWN_FW_HDR_598:
+ cts = (struct ieee80211_frame_cts *)
+ txhdr->body.r598.rts_frame;
+ break;
+ }
+
mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr,
protdur);
KASSERT(mprot != NULL, ("failed to alloc mbuf\n"));
@@ -6255,9 +6315,21 @@ bwn_set_txhdr(struct bwn_mac *mac, struc
macctl |= BWN_TX_MAC_SEND_CTSTOSELF;
len = sizeof(struct ieee80211_frame_cts);
} else {
- rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
- (txhdr->body.old.rts_frame) :
- (txhdr->body.new.rts_frame));
+ switch (mac->mac_fw.fw_hdr_format) {
+ case BWN_FW_HDR_351:
+ rts = (struct ieee80211_frame_rts *)
+ txhdr->body.r351.rts_frame;
+ break;
+ case BWN_FW_HDR_410:
+ rts = (struct ieee80211_frame_rts *)
+ txhdr->body.r410.rts_frame;
+ break;
+ case BWN_FW_HDR_598:
+ rts = (struct ieee80211_frame_rts *)
+ txhdr->body.r598.rts_frame;
+ break;
+ }
+
/* XXX rate/rate_fb is the hardware rate */
protdur += ieee80211_ack_duration(ic->ic_rt, rate,
isshort);
@@ -6271,15 +6343,40 @@ bwn_set_txhdr(struct bwn_mac *mac, struc
len = sizeof(struct ieee80211_frame_rts);
}
len += IEEE80211_CRC_LEN;
- bwn_plcp_genhdr((struct bwn_plcp4 *)((BWN_ISOLDFMT(mac)) ?
- &txhdr->body.old.rts_plcp :
- &txhdr->body.new.rts_plcp), len, rts_rate);
+
+ switch (mac->mac_fw.fw_hdr_format) {
+ case BWN_FW_HDR_351:
+ bwn_plcp_genhdr((struct bwn_plcp4 *)
+ &txhdr->body.r351.rts_plcp, len, rts_rate);
+ break;
+ case BWN_FW_HDR_410:
+ bwn_plcp_genhdr((struct bwn_plcp4 *)
+ &txhdr->body.r410.rts_plcp, len, rts_rate);
+ break;
+ case BWN_FW_HDR_598:
+ bwn_plcp_genhdr((struct bwn_plcp4 *)
+ &txhdr->body.r598.rts_plcp, len, rts_rate);
+ break;
+ }
+
bwn_plcp_genhdr((struct bwn_plcp4 *)&txhdr->rts_plcp_fb, len,
rts_rate_fb);
- protwh = (struct ieee80211_frame *)(BWN_ISOLDFMT(mac) ?
- (&txhdr->body.old.rts_frame) :
- (&txhdr->body.new.rts_frame));
+ switch (mac->mac_fw.fw_hdr_format) {
+ case BWN_FW_HDR_351:
+ protwh = (struct ieee80211_frame *)
+ &txhdr->body.r351.rts_frame;
+ break;
+ case BWN_FW_HDR_410:
+ protwh = (struct ieee80211_frame *)
+ &txhdr->body.r410.rts_frame;
+ break;
+ case BWN_FW_HDR_598:
+ protwh = (struct ieee80211_frame *)
+ &txhdr->body.r598.rts_frame;
+ break;
+ }
+
txhdr->rts_dur_fb = *(u_int16_t *)protwh->i_dur;
if (BWN_ISOFDMRATE(rts_rate)) {
@@ -6303,10 +6400,17 @@ bwn_set_txhdr(struct bwn_mac *mac, struc
txhdr->phyctl_1fb = htole16(bwn_set_txhdr_phyctl1(mac, rate_fb));
}
- if (BWN_ISOLDFMT(mac))
- txhdr->body.old.cookie = htole16(cookie);
- else
- txhdr->body.new.cookie = htole16(cookie);
+ switch (mac->mac_fw.fw_hdr_format) {
+ case BWN_FW_HDR_351:
+ txhdr->body.r351.cookie = htole16(cookie);
+ break;
+ case BWN_FW_HDR_410:
+ txhdr->body.r410.cookie = htole16(cookie);
+ break;
+ case BWN_FW_HDR_598:
+ txhdr->body.r598.cookie = htole16(cookie);
+ break;
+ }
txhdr->macctl = htole32(macctl);
txhdr->phyctl = htole16(phyctl);
@@ -6739,6 +6843,7 @@ bwn_rx_radiotap(struct bwn_mac *mac, str
const struct ieee80211_frame_min *wh;
uint64_t tsf;
uint16_t low_mactime_now;
+ uint16_t mt;
if (htole16(rxhdr->phy_status0) & BWN_RX_PHYST0_SHORTPRMBL)
sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
@@ -6750,8 +6855,19 @@ bwn_rx_radiotap(struct bwn_mac *mac, str
bwn_tsf_read(mac, &tsf);
low_mactime_now = tsf;
tsf = tsf & ~0xffffULL;
- tsf += le16toh(rxhdr->mac_time);
- if (low_mactime_now < le16toh(rxhdr->mac_time))
+
+ switch (mac->mac_fw.fw_hdr_format) {
+ case BWN_FW_HDR_351:
+ case BWN_FW_HDR_410:
+ mt = le16toh(rxhdr->ps4.r351.mac_time);
+ break;
+ case BWN_FW_HDR_598:
+ mt = le16toh(rxhdr->ps4.r598.mac_time);
+ break;
+ }
+
+ tsf += mt;
+ if (low_mactime_now < mt)
tsf -= 0x10000;
sc->sc_rx_th.wr_tsf = tsf;
Modified: head/sys/dev/bwn/if_bwnvar.h
==============================================================================
--- head/sys/dev/bwn/if_bwnvar.h Wed May 18 04:35:58 2016 (r300113)
+++ head/sys/dev/bwn/if_bwnvar.h Wed May 18 05:56:25 2016 (r300114)
@@ -271,10 +271,29 @@ struct bwn_rxhdr4 {
} __packed ht;
uint16_t phy_status2;
} __packed ps2;
- uint16_t phy_status3;
- uint32_t mac_status;
- uint16_t mac_time;
- uint16_t channel;
+ union {
+ struct {
+ uint16_t phy_status3;
+ } __packed lp;
+ struct {
+ int8_t phy_ht_power1;
+ int8_t phy_ht_power2;
+ } __packed ht;
+ } __packed ps3;
+ union {
+ struct {
+ uint32_t mac_status;
+ uint16_t mac_time;
+ uint16_t channel;
+ } __packed r351;
+ struct {
+ uint16_t phy_status4;
+ uint16_t phy_status5;
+ uint32_t mac_status;
+ uint16_t mac_time;
+ uint16_t channel;
+ } __packed r598;
+ } __packed ps4;
} __packed;
struct bwn_txstatus {
@@ -765,19 +784,34 @@ struct bwn_txhdr {
uint8_t rts_frame[16];
uint8_t pad1[2];
struct bwn_plcp6 plcp;
- } __packed old;
- /* format > r410 */
+ } __packed r351;
+ /* format > r410 < r598 */
+ struct {
+ uint16_t mimo_antenna;
+ uint16_t preload_size;
+ uint8_t pad0[2];
+ uint16_t cookie;
+ uint16_t tx_status;
+ struct bwn_plcp6 rts_plcp;
+ uint8_t rts_frame[16];
+ uint8_t pad1[2];
+ struct bwn_plcp6 plcp;
+ } __packed r410;
struct {
uint16_t mimo_antenna;
uint16_t preload_size;
uint8_t pad0[2];
uint16_t cookie;
uint16_t tx_status;
+ uint16_t max_n_mpdus;
+ uint16_t max_a_bytes_mrt;
+ uint16_t max_a_bytes_fbr;
+ uint16_t min_m_bytes;
struct bwn_plcp6 rts_plcp;
uint8_t rts_frame[16];
uint8_t pad1[2];
struct bwn_plcp6 plcp;
- } __packed new;
+ } __packed r598;
} __packed body;
} __packed;
More information about the svn-src-head
mailing list