Date: Wed, 18 May 2016 05:56:25 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r300114 - head/sys/dev/bwn Message-ID: <201605180556.u4I5uPu0049174@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605180556.u4I5uPu0049174>