Skip site navigation (1)Skip section navigation (2)
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>